diff --git a/Plugins/dnlib.dll b/Plugins/dnlib.dll new file mode 100644 index 0000000..ba1f36d Binary files /dev/null and b/Plugins/dnlib.dll differ diff --git a/Plugins/dnlib/DefaultDllImportSearchPathsAttribute.cs b/Plugins/dnlib/DefaultDllImportSearchPathsAttribute.cs deleted file mode 100644 index ad4b10d..0000000 --- a/Plugins/dnlib/DefaultDllImportSearchPathsAttribute.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -#if NET35 -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, - } -} -#endif diff --git a/Plugins/dnlib/DotNet/AllTypesHelper.cs b/Plugins/dnlib/DotNet/AllTypesHelper.cs deleted file mode 100644 index 2dcac1f..0000000 --- a/Plugins/dnlib/DotNet/AllTypesHelper.cs +++ /dev/null @@ -1,35 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Returns types without getting stuck in an infinite loop - /// - readonly struct AllTypesHelper { - /// - /// Gets a list of all types and nested types - /// - /// A list of types - public static IEnumerable Types(IEnumerable types) { - var visited = new Dictionary(); - var stack = new Stack>(); - if (types is not null) - stack.Push(types.GetEnumerator()); - while (stack.Count > 0) { - var enumerator = stack.Pop(); - while (enumerator.MoveNext()) { - var type = enumerator.Current; - if (visited.ContainsKey(type)) - continue; - visited[type] = true; - yield return type; - if (type.NestedTypes.Count > 0) { - stack.Push(enumerator); - enumerator = type.NestedTypes.GetEnumerator(); - } - } - } - } - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyAttributes.cs b/Plugins/dnlib/DotNet/AssemblyAttributes.cs deleted file mode 100644 index c4a687f..0000000 --- a/Plugins/dnlib/DotNet/AssemblyAttributes.cs +++ /dev/null @@ -1,58 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Assembly flags from Assembly.Flags column. - /// - /// See CorHdr.h/CorAssemblyFlags - [Flags] - public enum AssemblyAttributes : uint { - /// No flags set - None = 0, - - /// The assembly ref holds the full (unhashed) public key. - PublicKey = 1, - - /// Processor Architecture unspecified - PA_None = 0x0000, - /// Processor Architecture: neutral (PE32) - PA_MSIL = 0x0010, - /// Processor Architecture: x86 (PE32) - PA_x86 = 0x0020, - /// Processor Architecture: Itanium (PE32+) - PA_IA64 = 0x0030, - /// Processor Architecture: AMD X64 (PE32+) - 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 - PA_Specified = 0x0080, - /// Bits describing the processor architecture - PA_Mask = 0x0070, - /// Bits describing the PA incl. Specified - PA_FullMask = 0x00F0, - /// NOT A FLAG, shift count in PA flags <--> index conversion - PA_Shift = 0x0004, - - /// From "DebuggableAttribute". - EnableJITcompileTracking = 0x8000, - /// From "DebuggableAttribute". - DisableJITcompileOptimizer = 0x4000, - - /// The assembly can be retargeted (at runtime) to an assembly from a different publisher. - Retargetable = 0x0100, - - /// - ContentType_Default = 0x0000, - /// - ContentType_WindowsRuntime = 0x0200, - /// Bits describing ContentType - ContentType_Mask = 0x0E00, - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyDef.cs b/Plugins/dnlib/DotNet/AssemblyDef.cs deleted file mode 100644 index 0e89652..0000000 --- a/Plugins/dnlib/DotNet/AssemblyDef.cs +++ /dev/null @@ -1,1050 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Reflection; -using System.Threading; -using dnlib.Utils; -using dnlib.DotNet.MD; -using dnlib.DotNet.Writer; -using System.Text.RegularExpressions; -using dnlib.DotNet.Pdb; -using System.Collections.Generic; -using System.Diagnostics; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Assembly table - /// - public abstract class AssemblyDef : IHasCustomAttribute, IHasDeclSecurity, IHasCustomDebugInformation, IAssembly, IListListener, ITypeDefFinder, IDnlibDef { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.Assembly, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 14; - - /// - public int HasDeclSecurityTag => 2; - - /// - /// From column Assembly.HashAlgId - /// - public AssemblyHashAlgorithm HashAlgorithm { - get => hashAlgorithm; - set => hashAlgorithm = value; - } - /// - protected AssemblyHashAlgorithm hashAlgorithm; - - /// - /// From columns Assembly.MajorVersion, Assembly.MinorVersion, Assembly.BuildNumber, - /// Assembly.RevisionNumber. - /// - /// If is null - public Version Version { - get => version; - set => version = value ?? throw new ArgumentNullException(nameof(value)); - } - /// - protected Version version; - - /// - /// From column Assembly.Flags - /// - public AssemblyAttributes Attributes { - get => (AssemblyAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column Assembly.PublicKey - /// - /// An empty is created if the caller writes null - public PublicKey PublicKey { - get => publicKey; - set => publicKey = value ?? new PublicKey(); - } - /// - protected PublicKey publicKey; - - /// - /// Gets the public key token which is calculated from - /// - public PublicKeyToken PublicKeyToken => publicKey.Token; - - /// - /// From column Assembly.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column Assembly.Locale - /// - public UTF8String Culture { - get => culture; - set => culture = value; - } - /// Name - protected UTF8String culture; - - /// - public IList DeclSecurities { - get { - if (declSecurities is null) - InitializeDeclSecurities(); - return declSecurities; - } - } - /// - protected IList declSecurities; - /// Initializes - protected virtual void InitializeDeclSecurities() => - Interlocked.CompareExchange(ref declSecurities, new List(), null); - - /// - public PublicKeyBase PublicKeyOrToken => publicKey; - - /// - public string FullName => GetFullNameWithPublicKeyToken(); - - /// - public string FullNameToken => GetFullNameWithPublicKeyToken(); - - /// - /// Gets all modules. The first module is always the . - /// - public IList Modules { - get { - if (modules is null) - InitializeModules(); - return modules; - } - } - /// - protected LazyList modules; - /// Initializes - protected virtual void InitializeModules() => - Interlocked.CompareExchange(ref modules, new LazyList(this), null); - - /// - /// 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 => 14; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 HasDeclSecurities => DeclSecurities.Count > 0; - - /// - /// true if is not empty - /// - 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 => Modules.Count == 0 ? null : Modules[0]; - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(AssemblyAttributes andMask, AssemblyAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, AssemblyAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool HasPublicKey { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PublicKey); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitecture { - get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; - set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitectureFull { - get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; - set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); - } - - /// - /// true if unspecified processor architecture - /// - public bool IsProcessorArchitectureNone => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; - - /// - /// true if neutral (PE32) architecture - /// - public bool IsProcessorArchitectureMSIL => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; - - /// - /// true if x86 (PE32) architecture - /// - public bool IsProcessorArchitectureX86 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; - - /// - /// true if IA-64 (PE32+) architecture - /// - public bool IsProcessorArchitectureIA64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; - - /// - /// true if x64 (PE32+) architecture - /// - public bool IsProcessorArchitectureX64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; - - /// - /// true if ARM (PE32) architecture - /// - public bool IsProcessorArchitectureARM => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; - - /// - /// true if eg. reference assembly (not runnable) - /// - public bool IsProcessorArchitectureNoPlatform => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; - - /// - /// Gets/sets the bit - /// - public bool IsProcessorArchitectureSpecified { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); - } - - /// - /// Gets/sets the bit - /// - public bool EnableJITcompileTracking { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; - set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); - } - - /// - /// Gets/sets the bit - /// - public bool DisableJITcompileOptimizer { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; - set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); - } - - /// - /// Gets/sets the bit - /// - public bool IsRetargetable { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; - set => ModifyAttributes(value, AssemblyAttributes.Retargetable); - } - - /// - /// Gets/sets the content type - /// - public AssemblyAttributes ContentType { - get => (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; - set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); - } - - /// - /// true if content type is Default - /// - public bool IsContentTypeDefault => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; - - /// - /// true if content type is WindowsRuntime - /// - public bool IsContentTypeWindowsRuntime => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; - - /// - /// Finds a module in this assembly - /// - /// Name of module - /// A instance or null if it wasn't found. - public ModuleDef FindModule(UTF8String name) { - var modules = Modules; - int count = modules.Count; - for (int i = 0; i < count; i++) { - var module = modules[i]; - if (module is null) - continue; - if (UTF8String.CaseInsensitiveEquals(module.Name, name)) - return module; - } - return null; - } - - /// - /// Creates an instance from a file - /// - /// File name of an existing .NET assembly - /// Module context or 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(string fileName, ModuleContext context) => - Load(fileName, new ModuleCreationOptions(context)); - - /// - /// Creates an instance from a file - /// - /// File name of an existing .NET assembly - /// Module creation options or 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(string fileName, ModuleCreationOptions options = 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 is null) - throw new BadImageFormatException($"{fileName} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); - return asm; - } - catch { - if (module is not null) - module.Dispose(); - throw; - } - } - - /// - /// Creates an instance from a byte[] - /// - /// Contents of a .NET assembly - /// Module context or 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(byte[] data, ModuleContext context) => - Load(data, new ModuleCreationOptions(context)); - - /// - /// Creates an instance from a byte[] - /// - /// Contents of a .NET assembly - /// Module creation options or 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(byte[] data, ModuleCreationOptions options = 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 is null) - throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); - return asm; - } - catch { - if (module is not null) - module.Dispose(); - throw; - } - } - - /// - /// Creates an instance from a memory location - /// - /// Address of a .NET assembly - /// Module context or 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) => - Load(addr, new ModuleCreationOptions(context)); - - /// - /// Creates an instance from a memory location - /// - /// Address of a .NET assembly - /// Module creation options or 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, ModuleCreationOptions options = null) { - if (addr == IntPtr.Zero) - throw new ArgumentNullException(nameof(addr)); - ModuleDef module = null; - try { - module = ModuleDefMD.Load(addr, options); - var asm = module.Assembly; - 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 is not null) - module.Dispose(); - throw; - } - } - - /// - /// 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 - /// Module context or 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) => - Load(stream, new ModuleCreationOptions(context)); - - /// - /// 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 - /// Module creation options or 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, ModuleCreationOptions options = 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 is null) - throw new BadImageFormatException($"{module.ToString()} is only a .NET module, not a .NET assembly. Use ModuleDef.Load()."); - return asm; - } - catch { - if (module is not null) - module.Dispose(); - throw; - } - } - - /// - /// Gets the assembly name with the public key - /// - public string GetFullNameWithPublicKey() => FullNameFactory.AssemblyFullName(this, false); - - /// - /// Gets the assembly name with the public key token - /// - public string GetFullNameWithPublicKeyToken() => FullNameFactory.AssemblyFullName(this, true); - - /// - /// Finds a . For speed, enable - /// if possible (read the documentation first). - /// - /// Full name of the type (no assembly information) - /// true if it's a reflection name, and nested - /// 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) { - var modules = Modules; - int count = modules.Count; - for (int i = 0; i < count; i++) { - var module = modules[i]; - if (module is null) - continue; - var type = module.Find(fullName, isReflectionName); - if (type is not null) - return type; - } - return null; - } - - /// - /// Finds a . Its scope (i.e., module or assembly) is ignored when - /// looking up the type. For speed, enable - /// if possible (read the documentation first). - /// - /// The type ref - /// An existing or null if it wasn't found. - public TypeDef Find(TypeRef typeRef) { - var modules = Modules; - int count = modules.Count; - for (int i = 0; i < count; i++) { - var module = modules[i]; - if (module is null) - continue; - var type = module.Find(typeRef); - if (type is not null) - return type; - } - return 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 = null) => - ManifestModule.Write(filename, options); - - /// - /// Writes the assembly to a stream. - /// - /// Destination stream - /// Writer options - public void Write(Stream dest, ModuleWriterOptions options = null) => - ManifestModule.Write(dest, options); - - /// - /// Checks whether this assembly is a friend assembly of - /// - /// Target assembly - public bool IsFriendAssemblyOf(AssemblyDef targetAsm) { - if (targetAsm is null) - return false; - if (this == targetAsm) - return true; - - // Both must be unsigned or both must be signed according to the - // InternalsVisibleToAttribute documentation. - if (PublicKeyBase.IsNullOrEmpty2(publicKey) != PublicKeyBase.IsNullOrEmpty2(targetAsm.PublicKey)) - return false; - - foreach (var ca in targetAsm.CustomAttributes.FindAll("System.Runtime.CompilerServices.InternalsVisibleToAttribute")) { - if (ca.ConstructorArguments.Count != 1) - continue; - var arg = ca.ConstructorArguments.Count == 0 ? default : ca.ConstructorArguments[0]; - if (arg.Type.GetElementType() != ElementType.String) - continue; - var asmName = arg.Value as UTF8String; - if (UTF8String.IsNull(asmName)) - continue; - - var asmInfo = new AssemblyNameInfo(asmName); - if (asmInfo.Name != name) - continue; - if (!PublicKeyBase.IsNullOrEmpty2(publicKey)) { - if (!PublicKey.Equals(asmInfo.PublicKeyOrToken as PublicKey)) - continue; - } - else if (!PublicKeyBase.IsNullOrEmpty2(asmInfo.PublicKeyOrToken)) - continue; - - return true; - } - - return false; - } - - /// - /// Adds or updates an existing System.Reflection.AssemblySignatureKeyAttribute - /// attribute. This attribute is used in enhanced strong naming with key migration. - /// See http://msdn.microsoft.com/en-us/library/hh415055.aspx - /// - /// Identity public key - /// Identity strong name key pair - /// Signature public key - public void UpdateOrCreateAssemblySignatureKeyAttribute(StrongNamePublicKey identityPubKey, StrongNameKey identityKey, StrongNamePublicKey signaturePubKey) { - var manifestModule = ManifestModule; - if (manifestModule is null) - return; - - // Remove all existing attributes - CustomAttribute ca = null; - for (int i = 0; i < CustomAttributes.Count; i++) { - var caTmp = CustomAttributes[i]; - if (caTmp.TypeFullName != "System.Reflection.AssemblySignatureKeyAttribute") - continue; - CustomAttributes.RemoveAt(i); - i--; - if (ca is null) - ca = caTmp; - } - - if (IsValidAssemblySignatureKeyAttribute(ca)) - ca.NamedArguments.Clear(); - else - ca = CreateAssemblySignatureKeyAttribute(); - - var counterSig = StrongNameKey.CreateCounterSignatureAsString(identityPubKey, identityKey, signaturePubKey); - ca.ConstructorArguments[0] = new CAArgument(manifestModule.CorLibTypes.String, new UTF8String(signaturePubKey.ToString())); - ca.ConstructorArguments[1] = new CAArgument(manifestModule.CorLibTypes.String, new UTF8String(counterSig)); - CustomAttributes.Add(ca); - } - - bool IsValidAssemblySignatureKeyAttribute(CustomAttribute ca) { - if (dnlib.Settings.IsThreadSafe) - return false; - if (ca is null) - return false; - var ctor = ca.Constructor; - if (ctor is null) - return false; - var sig = ctor.MethodSig; - if (sig is null || sig.Params.Count != 2) - return false; - if (sig.Params[0].GetElementType() != ElementType.String) - return false; - if (sig.Params[1].GetElementType() != ElementType.String) - return false; - if (ca.ConstructorArguments.Count != 2) - return false; - return true; - } - - CustomAttribute CreateAssemblySignatureKeyAttribute() { - var manifestModule = ManifestModule; - var owner = manifestModule.UpdateRowId(new TypeRefUser(manifestModule, "System.Reflection", "AssemblySignatureKeyAttribute", manifestModule.CorLibTypes.AssemblyRef)); - var methodSig = MethodSig.CreateInstance(manifestModule.CorLibTypes.Void, manifestModule.CorLibTypes.String, manifestModule.CorLibTypes.String); - var ctor = manifestModule.UpdateRowId(new MemberRefUser(manifestModule, MethodDef.InstanceConstructorName, methodSig, owner)); - var ca = new CustomAttribute(ctor); - ca.ConstructorArguments.Add(new CAArgument(manifestModule.CorLibTypes.String, UTF8String.Empty)); - ca.ConstructorArguments.Add(new CAArgument(manifestModule.CorLibTypes.String, UTF8String.Empty)); - 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 is null) - return; -#if DEBUG - if (module.Assembly is null) - throw new InvalidOperationException("Module.Assembly is null"); -#endif - } - - /// - void IListListener.OnAdd(int index, ModuleDef module) { - if (module is null) - return; - 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 not null) - module.Assembly = null; - } - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var module in modules.GetEnumerable_NoLock()) { - if (module is not null) - module.Assembly = null; - } - } - - /// - public override string ToString() => FullName; - } - - /// - /// An Assembly row created by the user and not present in the original .NET file - /// - public class AssemblyDefUser : AssemblyDef { - /// - /// Default constructor - /// - public AssemblyDefUser() - : this(UTF8String.Empty, new Version(0, 0, 0, 0)) { - } - - /// - /// Constructor - /// - /// Simple name - /// If any of the args is invalid - public AssemblyDefUser(UTF8String name) - : this(name, new Version(0, 0, 0, 0), new PublicKey()) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// If any of the args is invalid - public AssemblyDefUser(UTF8String name, Version version) - : this(name, version, new PublicKey()) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// Public key - /// If any of the args is invalid - public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey) - : this(name, version, publicKey, UTF8String.Empty) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// Public key - /// Locale - /// If any of the args is invalid - public AssemblyDefUser(UTF8String name, Version version, PublicKey publicKey, UTF8String locale) { - if (name is null) - throw new ArgumentNullException(nameof(name)); - if (locale is null) - throw new ArgumentNullException(nameof(locale)); - modules = new LazyList(this); - this.name = name; - this.version = version ?? throw new ArgumentNullException(nameof(version)); - this.publicKey = publicKey ?? new PublicKey(); - culture = locale; - attributes = (int)AssemblyAttributes.None; - } - - /// - /// Constructor - /// - /// Assembly name info - /// If is null - public AssemblyDefUser(AssemblyName asmName) - : this(new AssemblyNameInfo(asmName)) { - hashAlgorithm = (AssemblyHashAlgorithm)asmName.HashAlgorithm; - attributes = (int)asmName.Flags; - } - - /// - /// Constructor - /// - /// Assembly name info - /// If is null - public AssemblyDefUser(IAssembly asmName) { - if (asmName is null) - 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; - } - } - - /// - /// Created from a row in the Assembly table - /// - sealed class AssemblyDefMD : AssemblyDef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeDeclSecurities() { - var list = readerModule.Metadata.GetDeclSecurityRidList(Table.Assembly, origRid); - var tmp = new LazyList(list.Count, list, (list2, index) => readerModule.ResolveDeclSecurity(list2[index])); - Interlocked.CompareExchange(ref declSecurities, tmp, null); - } - - /// - protected override void InitializeModules() { - var list = readerModule.GetModuleRidList(); - var tmp = new LazyList(list.Count + 1, this, list, (list2, index) => { - ModuleDef module; - if (index == 0) - module = readerModule; - else - module = readerModule.ReadModule(list2[index - 1], this); - if (module is null) - module = new ModuleDefUser("INVALID", Guid.NewGuid()); - module.Assembly = this; - return module; - }); - Interlocked.CompareExchange(ref modules, tmp, null); - } - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.Assembly, 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 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]; - if (!readerModule.TablesStream.TryReadCustomAttributeRow(caRid, out var caRow)) - continue; - var caType = readerModule.ResolveCustomAttributeType(caRow.Type, gpContext); - if (!TryGetName(caType, out var ns, out var name)) - continue; - if (ns != nameSystemRuntimeVersioning || name != nameTargetFrameworkAttribute) - continue; - var ca = CustomAttributeReader.Read(readerModule, caType, caRow.Value, gpContext); - if (ca is null || ca.ConstructorArguments.Count != 1) - continue; - var s = ca.ConstructorArguments[0].Value as UTF8String; - if (s is null) - continue; - if (TryCreateTargetFrameworkInfo(s, out var tmpFramework, out var tmpVersion, out var 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) { - ITypeDefOrRef type; - if (caType is MemberRef mr) - type = mr.DeclaringType; - else - type = (caType as MethodDef)?.DeclaringType; - if (type is TypeRef tr) { - ns = tr.Namespace; - name = tr.Name; - return true; - } - if (type is TypeDef td) { - 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 is null) - return false; - - framework = frameworkRes; - version = versionRes; - profile = profileRes; - return true; - } - - static int ParseInt32(string s) => int.TryParse(s, out int 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 - /// - /// The module which contains this Assembly row - /// Row ID - /// If is null - /// If is invalid - public AssemblyDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.AssemblyTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Assembly rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - if (rid != 1) - modules = new LazyList(this); - bool b = readerModule.TablesStream.TryReadAssemblyRow(origRid, out var row); - Debug.Assert(b); - hashAlgorithm = (AssemblyHashAlgorithm)row.HashAlgId; - version = new Version(row.MajorVersion, row.MinorVersion, row.BuildNumber, row.RevisionNumber); - attributes = (int)row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - culture = readerModule.StringsStream.ReadNoNull(row.Locale); - publicKey = new PublicKey(readerModule.BlobStream.Read(row.PublicKey)); - } - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyHash.cs b/Plugins/dnlib/DotNet/AssemblyHash.cs deleted file mode 100644 index 22de5f3..0000000 --- a/Plugins/dnlib/DotNet/AssemblyHash.cs +++ /dev/null @@ -1,111 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Security.Cryptography; - -namespace dnlib.DotNet { - /// - /// Hashes some data according to a - /// - readonly struct AssemblyHash : IDisposable { - readonly HashAlgorithm hasher; - - /// - /// Constructor - /// - /// If is an unsupported hash algorithm, then - /// will be used as the hash algorithm. - /// The algorithm to use - 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() { - if (hasher is not null) - ((IDisposable)hasher).Dispose(); - } - - /// - /// Hash data - /// - /// If is an unsupported hash algorithm, then - /// will be used as the hash algorithm. - /// The data - /// The algorithm to use - /// Hashed data or null if was null - public static byte[] Hash(byte[] data, AssemblyHashAlgorithm hashAlgo) { - if (data is null) - return null; - - using (var asmHash = new AssemblyHash(hashAlgo)) { - asmHash.Hash(data); - return asmHash.ComputeHash(); - } - } - - /// - /// Hash data - /// - /// Data - public void Hash(byte[] data) => Hash(data, 0, data.Length); - - /// - /// Hash data - /// - /// Data - /// Offset - /// Length - public void Hash(byte[] data, int offset, int length) { - if (hasher.TransformBlock(data, offset, length, data, offset) != length) - throw new IOException("Could not calculate hash"); - } - - /// - /// Hash stream data - /// - /// Stream - /// Number of bytes to hash - /// Temp buffer - public void Hash(Stream stream, uint length, byte[] buffer) { - while (length > 0) { - int len = length > (uint)buffer.Length ? buffer.Length : (int)length; - if (stream.Read(buffer, 0, len) != len) - throw new IOException("Could not read data"); - Hash(buffer, 0, len); - length -= (uint)len; - } - } - - /// - /// Computes the hash - /// - public byte[] ComputeHash() { - hasher.TransformFinalBlock(Array2.Empty(), 0, 0); - return hasher.Hash; - } - - /// - /// Creates a public key token from the hash of some - /// - /// A public key is hashed, and the last 8 bytes of the hash, in reverse - /// order, is used as the public key token - /// The data - /// A new instance - public static PublicKeyToken CreatePublicKeyToken(byte[] publicKeyData) { - if (publicKeyData is null) - return new PublicKeyToken(); - var hash = Hash(publicKeyData, AssemblyHashAlgorithm.SHA1); - 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/Plugins/dnlib/DotNet/AssemblyHashAlgorithm.cs b/Plugins/dnlib/DotNet/AssemblyHashAlgorithm.cs deleted file mode 100644 index 8c5913c..0000000 --- a/Plugins/dnlib/DotNet/AssemblyHashAlgorithm.cs +++ /dev/null @@ -1,54 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Any ALG_CLASS_HASH type in WinCrypt.h can be used by Microsoft's CLI implementation - /// - public enum AssemblyHashAlgorithm : uint { - /// - None = 0, - /// - MD2 = 0x8001, - /// - MD4 = 0x8002, - /// This is a reserved value in the CLI - MD5 = 0x8003, - /// The only algorithm supported by the CLI - SHA1 = 0x8004, - /// - MAC = 0x8005, - /// - SSL3_SHAMD5 = 0x8008, - /// - HMAC = 0x8009, - /// - TLS1PRF = 0x800A, - /// - HASH_REPLACE_OWF = 0x800B, - /// - SHA_256 = 0x800C, - /// - SHA_384 = 0x800D, - /// - SHA_512 = 0x800E, - } - - public static partial class Extensions { - 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/Plugins/dnlib/DotNet/AssemblyNameComparer.cs b/Plugins/dnlib/DotNet/AssemblyNameComparer.cs deleted file mode 100644 index 4c4a078..0000000 --- a/Plugins/dnlib/DotNet/AssemblyNameComparer.cs +++ /dev/null @@ -1,259 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Flags used by - /// - [Flags] - public enum AssemblyNameComparerFlags { - /// - /// Compare assembly simple name - /// - Name = 1, - - /// - /// Compare assembly version - /// - Version = 2, - - /// - /// Compare assembly public key token - /// - PublicKeyToken = 4, - - /// - /// Compare assembly culture - /// - Culture = 8, - - /// - /// Compare content type - /// - ContentType = 0x10, - - /// - /// Compare assembly simple name, version, public key token, locale and content type - /// - All = Name | Version | PublicKeyToken | Culture | ContentType, - } - - /// - /// Compares two assembly names - /// - public readonly struct AssemblyNameComparer : IEqualityComparer { - /// - /// Compares the name, version, public key token, culture and content type - /// - public static readonly AssemblyNameComparer CompareAll = new AssemblyNameComparer(AssemblyNameComparerFlags.All); - - /// - /// Compares only the name and the public key token - /// - public static readonly AssemblyNameComparer NameAndPublicKeyTokenOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name | AssemblyNameComparerFlags.PublicKeyToken); - - /// - /// Compares only the name - /// - public static readonly AssemblyNameComparer NameOnly = new AssemblyNameComparer(AssemblyNameComparerFlags.Name); - - readonly AssemblyNameComparerFlags flags; - - /// - /// Gets the bit - /// - public bool CompareName => (flags & AssemblyNameComparerFlags.Name) != 0; - - /// - /// Gets the bit - /// - public bool CompareVersion => (flags & AssemblyNameComparerFlags.Version) != 0; - - /// - /// Gets the bit - /// - public bool ComparePublicKeyToken => (flags & AssemblyNameComparerFlags.PublicKeyToken) != 0; - - /// - /// Gets the bit - /// - public bool CompareCulture => (flags & AssemblyNameComparerFlags.Culture) != 0; - - /// - /// Gets the bit - /// - public bool CompareContentType => (flags & AssemblyNameComparerFlags.ContentType) != 0; - - /// - /// Constructor - /// - /// Comparison flags - public AssemblyNameComparer(AssemblyNameComparerFlags flags) => this.flags = flags; - - /// - /// Compares two assembly names - /// - /// First - /// Second - /// < 0 if a < b, 0 if a == b, > 0 if a > b - public int CompareTo(IAssembly a, IAssembly b) { - if (a == b) - return 0; - if (a is null) - return -1; - if (b is null) - return 1; - - int v; - - if (CompareName && (v = UTF8String.CaseInsensitiveCompareTo(a.Name, b.Name)) != 0) - return v; - if (CompareVersion && (v = Utils.CompareTo(a.Version, b.Version)) != 0) - return v; - if (ComparePublicKeyToken && (v = PublicKeyBase.TokenCompareTo(a.PublicKeyOrToken, b.PublicKeyOrToken)) != 0) - return v; - if (CompareCulture && (v = Utils.LocaleCompareTo(a.Culture, b.Culture)) != 0) - return v; - if (CompareContentType && (v = a.ContentType.CompareTo(b.ContentType)) != 0) - return v; - - return 0; - } - - /// - /// Compares two assembly names - /// - /// First - /// Second - /// true if equal, false otherwise - public bool Equals(IAssembly a, IAssembly b) => CompareTo(a, b) == 0; - - /// - /// Figures out which of two assembly names is closer to another assembly name - /// - /// Requested assembly name - /// First - /// Second - /// -1 if both are equally close, 0 if is closest, 1 if - /// is closest - public int CompareClosest(IAssembly requested, IAssembly a, IAssembly b) { - if (a == b) - return 0; - if (a is null) - return !CompareName ? 1 : UTF8String.CaseInsensitiveEquals(requested.Name, b.Name) ? 1 : 0; - if (b is null) - return !CompareName ? 0 : UTF8String.CaseInsensitiveEquals(requested.Name, a.Name) ? 0 : 1; - - // Compare the most important parts first: - // 1. Assembly simple name - // 2. Public key token - // 3. Version - // 4. Locale - // 5. Content type - - if (CompareName) { - // If the name only matches one of a or b, return that one. - bool na = UTF8String.CaseInsensitiveEquals(requested.Name, a.Name); - bool nb = UTF8String.CaseInsensitiveEquals(requested.Name, b.Name); - if (na && !nb) - return 0; - if (!na && nb) - return 1; - if (!na && !nb) - return -1; - } - - if (ComparePublicKeyToken) { - bool pa, pb; - if (PublicKeyBase.IsNullOrEmpty2(requested.PublicKeyOrToken)) { - // If one of them has a pkt but the other one hasn't, return the one with - // no pkt. - pa = PublicKeyBase.IsNullOrEmpty2(a.PublicKeyOrToken); - pb = PublicKeyBase.IsNullOrEmpty2(b.PublicKeyOrToken); - } - else { - // If one of them has the correct pkt, but the other one has an incorrect - // pkt, return the one with the correct pkt. - pa = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, a.PublicKeyOrToken); - pb = PublicKeyBase.TokenEquals(requested.PublicKeyOrToken, b.PublicKeyOrToken); - } - if (pa && !pb) - return 0; - if (!pa && pb) - return 1; - } - - if (CompareVersion && !Utils.Equals(a.Version, b.Version)) { - var rv = Utils.CreateVersionWithNoUndefinedValues(requested.Version); - if (rv == new Version(0, 0, 0, 0)) - rv = new Version(ushort.MaxValue, ushort.MaxValue, ushort.MaxValue, ushort.MaxValue); - int va = Utils.CompareTo(a.Version, rv); - int vb = Utils.CompareTo(b.Version, rv); - if (va == 0) - return 0; // vb != 0 so return 0 - if (vb == 0) - return 1; // va != 0 so return 1 - if (va > 0 && vb < 0) - return 0; - if (va < 0 && vb > 0) - return 1; - // Now either both a and b's version > req version or both are < req version - if (va > 0) { - // a.Version and b.Version > req.Version. Pick the one that is closest. - return Utils.CompareTo(a.Version, b.Version) < 0 ? 0 : 1; - } - else { - // a.Version and b.Version < req.Version. Pick the one that is closest. - return Utils.CompareTo(a.Version, b.Version) > 0 ? 0 : 1; - } - } - - if (CompareCulture) { - bool la = Utils.LocaleEquals(requested.Culture, a.Culture); - bool lb = Utils.LocaleEquals(requested.Culture, b.Culture); - if (la && !lb) - return 0; - if (!la && lb) - return 1; - } - - if (CompareContentType) { - bool ca = requested.ContentType == a.ContentType; - bool cb = requested.ContentType == b.ContentType; - if (ca && !cb) - return 0; - if (!ca && cb) - return 1; - } - - return -1; - } - - /// - /// Gets the hash code of an assembly name - /// - /// Assembly name - /// The hash code - public int GetHashCode(IAssembly a) { - if (a is null) - return 0; - - int hash = 0; - - if (CompareName) - hash += UTF8String.GetHashCode(a.Name); - if (CompareVersion) - hash += Utils.CreateVersionWithNoUndefinedValues(a.Version).GetHashCode(); - if (ComparePublicKeyToken) - hash += PublicKeyBase.GetHashCodeToken(a.PublicKeyOrToken); - if (CompareCulture) - hash += Utils.GetHashCodeLocale(a.Culture); - if (CompareContentType) - hash += (int)a.ContentType; - - return hash; - } - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyNameInfo.cs b/Plugins/dnlib/DotNet/AssemblyNameInfo.cs deleted file mode 100644 index 9e76d40..0000000 --- a/Plugins/dnlib/DotNet/AssemblyNameInfo.cs +++ /dev/null @@ -1,255 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Reflection; - -namespace dnlib.DotNet { - /// - /// Stores assembly name information - /// - public sealed class AssemblyNameInfo : IAssembly { - AssemblyHashAlgorithm hashAlgId; - Version version; - AssemblyAttributes flags; - PublicKeyBase publicKeyOrToken; - UTF8String name; - UTF8String culture; - - /// - /// Gets/sets the - /// - public AssemblyHashAlgorithm HashAlgId { - get => hashAlgId; - set => hashAlgId = value; - } - - /// - /// Gets/sets the or null if none specified - /// - public Version Version { - get => version; - set => version = value; - } - - /// - /// Gets/sets the - /// - public AssemblyAttributes Attributes { - get => flags; - set => flags = value; - } - - /// - /// Gets/sets the public key or token - /// - public PublicKeyBase PublicKeyOrToken { - get => publicKeyOrToken; - set => publicKeyOrToken = value; - } - - /// - /// Gets/sets the name - /// - public UTF8String Name { - get => name; - set => name = value; - } - - /// - /// Gets/sets the culture or null if none specified - /// - public UTF8String Culture { - get => culture; - set => culture = value; - } - - /// - /// Gets the full name of the assembly - /// - public string FullName => FullNameToken; - - /// - /// Gets the full name of the assembly but use a public key token - /// - public string FullNameToken => FullNameFactory.AssemblyFullName(this, true); - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(AssemblyAttributes andMask, AssemblyAttributes orMask) => Attributes = (Attributes & andMask) | orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, AssemblyAttributes flags) { - if (set) - Attributes |= flags; - else - Attributes &= ~flags; - } - - /// - /// Gets/sets the bit - /// - public bool HasPublicKey { - get => (Attributes & AssemblyAttributes.PublicKey) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PublicKey); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitecture { - get => Attributes & AssemblyAttributes.PA_Mask; - set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitectureFull { - get => Attributes & AssemblyAttributes.PA_FullMask; - set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); - } - - /// - /// true if unspecified processor architecture - /// - public bool IsProcessorArchitectureNone => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; - - /// - /// true if neutral (PE32) architecture - /// - public bool IsProcessorArchitectureMSIL => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; - - /// - /// true if x86 (PE32) architecture - /// - public bool IsProcessorArchitectureX86 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; - - /// - /// true if IA-64 (PE32+) architecture - /// - public bool IsProcessorArchitectureIA64 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; - - /// - /// true if x64 (PE32+) architecture - /// - public bool IsProcessorArchitectureX64 => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; - - /// - /// true if ARM (PE32) architecture - /// - public bool IsProcessorArchitectureARM => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; - - /// - /// true if eg. reference assembly (not runnable) - /// - public bool IsProcessorArchitectureNoPlatform => (Attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; - - /// - /// Gets/sets the bit - /// - public bool IsProcessorArchitectureSpecified { - get => (Attributes & AssemblyAttributes.PA_Specified) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); - } - - /// - /// Gets/sets the bit - /// - public bool EnableJITcompileTracking { - get => (Attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; - set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); - } - - /// - /// Gets/sets the bit - /// - public bool DisableJITcompileOptimizer { - get => (Attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; - set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); - } - - /// - /// Gets/sets the bit - /// - public bool IsRetargetable { - get => (Attributes & AssemblyAttributes.Retargetable) != 0; - set => ModifyAttributes(value, AssemblyAttributes.Retargetable); - } - - /// - /// Gets/sets the content type - /// - public AssemblyAttributes ContentType { - get => Attributes & AssemblyAttributes.ContentType_Mask; - set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); - } - - /// - /// true if content type is Default - /// - public bool IsContentTypeDefault => (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; - - /// - /// true if content type is WindowsRuntime - /// - public bool IsContentTypeWindowsRuntime => (Attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; - - /// - /// Default constructor - /// - public AssemblyNameInfo() { - } - - /// - /// Constructor - /// - /// An assembly name - public AssemblyNameInfo(string asmFullName) - : this(ReflectionTypeNameParser.ParseAssemblyRef(asmFullName)) { - } - - /// - /// Constructor - /// - /// The assembly - public AssemblyNameInfo(IAssembly asm) { - if (asm is null) - return; - var asmDef = asm as AssemblyDef; - hashAlgId = asmDef is 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; - } - - /// - /// Constructor - /// - /// Assembly name info - public AssemblyNameInfo(AssemblyName asmName) { - if (asmName is null) - return; - 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()); - name = asmName.Name ?? string.Empty; - culture = asmName.CultureInfo is not null && asmName.CultureInfo.Name is not null ? asmName.CultureInfo.Name : string.Empty; - } - - /// - public override string ToString() => FullName; - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyRef.cs b/Plugins/dnlib/DotNet/AssemblyRef.cs deleted file mode 100644 index f025cff..0000000 --- a/Plugins/dnlib/DotNet/AssemblyRef.cs +++ /dev/null @@ -1,466 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Reflection; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the AssemblyRef table - /// - 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 - /// when it references a type in the current assembly). - /// - public static readonly AssemblyRef CurrentAssembly = new AssemblyRefUser("<<>>"); - - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.AssemblyRef, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 15; - - /// - public int ImplementationTag => 1; - - /// - public int ResolutionScopeTag => 2; - - /// - public ScopeType ScopeType => ScopeType.AssemblyRef; - - /// - public string ScopeName => FullName; - - /// - /// From columns AssemblyRef.MajorVersion, AssemblyRef.MinorVersion, - /// AssemblyRef.BuildNumber, AssemblyRef.RevisionNumber - /// - /// If is null - public Version Version { - get => version; - set => version = value ?? throw new ArgumentNullException(nameof(value)); - } - /// - protected Version version; - - /// - /// From column AssemblyRef.Flags - /// - public AssemblyAttributes Attributes { - get => (AssemblyAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column AssemblyRef.PublicKeyOrToken - /// - /// If is null - public PublicKeyBase PublicKeyOrToken { - get => publicKeyOrToken; - set => publicKeyOrToken = value ?? throw new ArgumentNullException(nameof(value)); - } - /// - protected PublicKeyBase publicKeyOrToken; - - /// - /// From column AssemblyRef.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column AssemblyRef.Locale - /// - public UTF8String Culture { - get => culture; - set => culture = value; - } - /// Culture - protected UTF8String culture; - - /// - /// From column AssemblyRef.HashValue - /// - public byte[] Hash { - get => hashValue; - set => hashValue = value; - } - /// - protected byte[] hashValue; - - /// - /// 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 => 15; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 string FullName => FullNameToken; - - /// - /// Same as , except that it uses the PublicKey if available. - /// - public string RealFullName => FullNameFactory.AssemblyFullName(this, false); - - /// - /// Gets the full name of the assembly but use a public key token - /// - public string FullNameToken => FullNameFactory.AssemblyFullName(this, true); - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(AssemblyAttributes andMask, AssemblyAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, AssemblyAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool HasPublicKey { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.PublicKey) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PublicKey); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitecture { - get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask; - set => ModifyAttributes(~AssemblyAttributes.PA_Mask, value & AssemblyAttributes.PA_Mask); - } - - /// - /// Gets/sets the processor architecture - /// - public AssemblyAttributes ProcessorArchitectureFull { - get => (AssemblyAttributes)attributes & AssemblyAttributes.PA_FullMask; - set => ModifyAttributes(~AssemblyAttributes.PA_FullMask, value & AssemblyAttributes.PA_FullMask); - } - - /// - /// true if unspecified processor architecture - /// - public bool IsProcessorArchitectureNone => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_None; - - /// - /// true if neutral (PE32) architecture - /// - public bool IsProcessorArchitectureMSIL => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_MSIL; - - /// - /// true if x86 (PE32) architecture - /// - public bool IsProcessorArchitectureX86 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_x86; - - /// - /// true if IA-64 (PE32+) architecture - /// - public bool IsProcessorArchitectureIA64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_IA64; - - /// - /// true if x64 (PE32+) architecture - /// - public bool IsProcessorArchitectureX64 => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_AMD64; - - /// - /// true if ARM (PE32) architecture - /// - public bool IsProcessorArchitectureARM => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_ARM; - - /// - /// true if eg. reference assembly (not runnable) - /// - public bool IsProcessorArchitectureNoPlatform => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Mask) == AssemblyAttributes.PA_NoPlatform; - - /// - /// Gets/sets the bit - /// - public bool IsProcessorArchitectureSpecified { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.PA_Specified) != 0; - set => ModifyAttributes(value, AssemblyAttributes.PA_Specified); - } - - /// - /// Gets/sets the bit - /// - public bool EnableJITcompileTracking { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.EnableJITcompileTracking) != 0; - set => ModifyAttributes(value, AssemblyAttributes.EnableJITcompileTracking); - } - - /// - /// Gets/sets the bit - /// - public bool DisableJITcompileOptimizer { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.DisableJITcompileOptimizer) != 0; - set => ModifyAttributes(value, AssemblyAttributes.DisableJITcompileOptimizer); - } - - /// - /// Gets/sets the bit - /// - public bool IsRetargetable { - get => ((AssemblyAttributes)attributes & AssemblyAttributes.Retargetable) != 0; - set => ModifyAttributes(value, AssemblyAttributes.Retargetable); - } - - /// - /// Gets/sets the content type - /// - public AssemblyAttributes ContentType { - get => (AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask; - set => ModifyAttributes(~AssemblyAttributes.ContentType_Mask, value & AssemblyAttributes.ContentType_Mask); - } - - /// - /// true if content type is Default - /// - public bool IsContentTypeDefault => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_Default; - - /// - /// true if content type is WindowsRuntime - /// - public bool IsContentTypeWindowsRuntime => ((AssemblyAttributes)attributes & AssemblyAttributes.ContentType_Mask) == AssemblyAttributes.ContentType_WindowsRuntime; - - /// - public override string ToString() => FullName; - } - - /// - /// An AssemblyRef row created by the user and not present in the original .NET file - /// - public class AssemblyRefUser : AssemblyRef { - /// - /// Creates a reference to CLR 1.0's mscorlib - /// - 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() => 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() => 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() => new AssemblyRefUser("mscorlib", new Version(4, 0, 0, 0), new PublicKeyToken("b77a5c561934e089")); - - /// - /// Default constructor - /// - public AssemblyRefUser() - : this(UTF8String.Empty) { - } - - /// - /// Constructor - /// - /// Simple name - /// If any of the args is invalid - public AssemblyRefUser(UTF8String name) - : this(name, new Version(0, 0, 0, 0)) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// If any of the args is invalid - public AssemblyRefUser(UTF8String name, Version version) - : this(name, version, new PublicKey()) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// Public key or public key token - /// If any of the args is invalid - public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey) - : this(name, version, publicKey, UTF8String.Empty) { - } - - /// - /// Constructor - /// - /// Simple name - /// Version - /// Public key or public key token - /// Locale - /// If any of the args is invalid - public AssemblyRefUser(UTF8String name, Version version, PublicKeyBase publicKey, UTF8String locale) { - if (name is null) - throw new ArgumentNullException(nameof(name)); - if (locale is null) - throw new ArgumentNullException(nameof(locale)); - this.name = name; - this.version = version ?? throw new ArgumentNullException(nameof(version)); - publicKeyOrToken = publicKey; - culture = locale; - attributes = (int)(publicKey is PublicKey ? AssemblyAttributes.PublicKey : AssemblyAttributes.None); - } - - /// - /// Constructor - /// - /// Assembly name info - /// If is null - public AssemblyRefUser(AssemblyName asmName) - : this(new AssemblyNameInfo(asmName)) => attributes = (int)asmName.Flags; - - /// - /// Constructor - /// - /// Assembly - public AssemblyRefUser(IAssembly assembly) { - if (assembly is null) - throw new ArgumentNullException("asmName"); - - 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); - } - } - - /// - /// Created from a row in the AssemblyRef table - /// - sealed class AssemblyRefMD : AssemblyRef, 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.AssemblyRef, 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); - } - - /// - /// Constructor - /// - /// The module which contains this AssemblyRef row - /// Row ID - /// If is null - /// If is invalid - public AssemblyRefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.AssemblyRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"AssemblyRef rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadAssemblyRefRow(origRid, out var row); - Debug.Assert(b); - version = new Version(row.MajorVersion, row.MinorVersion, row.BuildNumber, row.RevisionNumber); - attributes = (int)row.Flags; - var pkData = readerModule.BlobStream.Read(row.PublicKeyOrToken); - if ((attributes & (uint)AssemblyAttributes.PublicKey) != 0) - publicKeyOrToken = new PublicKey(pkData); - else - publicKeyOrToken = new PublicKeyToken(pkData); - name = readerModule.StringsStream.ReadNoNull(row.Name); - culture = readerModule.StringsStream.ReadNoNull(row.Locale); - hashValue = readerModule.BlobStream.Read(row.HashValue); - } - } -} diff --git a/Plugins/dnlib/DotNet/AssemblyResolver.cs b/Plugins/dnlib/DotNet/AssemblyResolver.cs deleted file mode 100644 index 356da04..0000000 --- a/Plugins/dnlib/DotNet/AssemblyResolver.cs +++ /dev/null @@ -1,832 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// Resolves assemblies - /// - public class AssemblyResolver : IAssemblyResolver { - static readonly ModuleDef nullModule = new ModuleDefUser(); - - // DLL files are searched before EXE files - static readonly string[] assemblyExtensions = new string[] { ".dll", ".exe" }; - static readonly string[] winMDAssemblyExtensions = new string[] { ".winmd" }; - - static readonly List gacInfos; - static readonly string[] extraMonoPaths; - static readonly string[] monoVerDirs = new string[] { - // 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", - }; - - ModuleContext defaultModuleContext; - readonly Dictionary> moduleSearchPaths = new Dictionary>(); - readonly Dictionary cachedAssemblies = new Dictionary(StringComparer.OrdinalIgnoreCase); - readonly List preSearchPaths = new List(); - readonly List postSearchPaths = new List(); - bool findExactMatch; - bool enableFrameworkRedirect; - bool enableTypeDefCache = true; - bool useGac = true; -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - sealed class GacInfo { - public readonly int Version; - public readonly string Path; - public readonly string Prefix; - public readonly string[] SubDirs; - - public GacInfo(int version, string prefix, string path, string[] subDirs) { - Version = version; - Prefix = prefix; - Path = path; - SubDirs = subDirs; - } - } - - static AssemblyResolver() { - gacInfos = new List(); - - if (Type.GetType("Mono.Runtime") is not null) { - var dirs = new Dictionary(StringComparer.OrdinalIgnoreCase); - 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)) - continue; - dirs[dir] = true; - - if (Directory.Exists(dir)) { - gacInfos.Add(new GacInfo(-1, "", Path.GetDirectoryName(dir), new string[] { - Path.GetFileName(dir) - })); - } - - dir = Path.GetDirectoryName(dir); - foreach (var verDir in monoVerDirs) { - var dir2 = dir; - foreach (var d in verDir.Split(new char[] { '\\' })) - dir2 = Path.Combine(dir2, d); - if (Directory.Exists(dir2)) - extraMonoPathsList.Add(dir2); - } - } - - var paths = Environment.GetEnvironmentVariable("MONO_PATH"); - if (paths is not null) { - foreach (var tmp in paths.Split(Path.PathSeparator)) { - var path = tmp.Trim(); - if (path != string.Empty && Directory.Exists(path)) - extraMonoPathsList.Add(path); - } - } - extraMonoPaths = extraMonoPathsList.ToArray(); - } - else { - var windir = Environment.GetEnvironmentVariable("WINDIR"); - if (!string.IsNullOrEmpty(windir)) { - string path; - - // .NET Framework 1.x and 2.x - path = Path.Combine(windir, "assembly"); - if (Directory.Exists(path)) { - gacInfos.Add(new GacInfo(2, "", path, new string[] { - "GAC_32", "GAC_64", "GAC_MSIL", "GAC" - })); - } - - // .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[] { - "GAC_32", "GAC_64", "GAC_MSIL" - })); - } - } - } - } - - static string GetCurrentMonoPrefix() { - var path = typeof(object).Module.FullyQualifiedName; - for (int i = 0; i < 4; i++) - path = Path.GetDirectoryName(path); - return path; - } - - static IEnumerable FindMonoPrefixes() { - yield return GetCurrentMonoPrefix(); - - var prefixes = Environment.GetEnvironmentVariable("MONO_GAC_PREFIX"); - if (!string.IsNullOrEmpty(prefixes)) { - foreach (var tmp in prefixes.Split(Path.PathSeparator)) { - var prefix = tmp.Trim(); - if (prefix != string.Empty) - yield return prefix; - } - } - } - - /// - /// Gets/sets the default - /// - public ModuleContext DefaultModuleContext { - get => defaultModuleContext; - set => defaultModuleContext = value; - } - - /// - /// true if should find an assembly that matches exactly. - /// false if it first tries to match exactly, and if that fails, it picks an - /// assembly that is closest to the requested assembly. - /// - public bool FindExactMatch { - get => findExactMatch; - set => findExactMatch = value; - } - - /// - /// true if resolved .NET framework assemblies can be redirected to the source - /// 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 { - get => enableFrameworkRedirect; - set => enableFrameworkRedirect = value; - } - - /// - /// If true, all modules in newly resolved assemblies will have their - /// property set to true. This is - /// enabled by default since these modules shouldn't be modified by the user. - /// - public bool EnableTypeDefCache { - get => enableTypeDefCache; - set => enableTypeDefCache = value; - } - - /// - /// true to search the Global Assembly Cache. Default value is true. - /// - public bool UseGAC { - get => useGac; - set => useGac = value; - } - - /// - /// Gets paths searched before trying the standard locations - /// - public IList PreSearchPaths => preSearchPaths; - - /// - /// Gets paths searched after trying the standard locations - /// - public IList PostSearchPaths => postSearchPaths; - - /// - /// Default constructor - /// - public AssemblyResolver() - : this(null) { - } - - /// - /// Constructor - /// - /// Module context for all resolved assemblies - public AssemblyResolver(ModuleContext defaultModuleContext) { - this.defaultModuleContext = defaultModuleContext; - enableFrameworkRedirect = true; - } - - /// - public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) { - if (assembly is null) - return null; - - if (EnableFrameworkRedirect && !FindExactMatch) - FrameworkRedirect.ApplyFrameworkRedirect(ref assembly, sourceModule); - -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - var resolvedAssembly = Resolve2(assembly, sourceModule); - if (resolvedAssembly is null) { - string asmName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - string asmNameTrimmed = asmName.Trim(); - if (asmName != asmNameTrimmed) { - assembly = new AssemblyNameInfo { - Name = asmNameTrimmed, - Version = assembly.Version, - PublicKeyOrToken = assembly.PublicKeyOrToken, - Culture = assembly.Culture, - }; - resolvedAssembly = Resolve2(assembly, sourceModule); - } - } - - 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; - return null; - } - - var key1 = GetAssemblyNameKey(resolvedAssembly); - var key2 = GetAssemblyNameKey(assembly); - cachedAssemblies.TryGetValue(key1, out var asm1); - cachedAssemblies.TryGetValue(key2, out var asm2); - - if (asm1 != resolvedAssembly && asm2 != resolvedAssembly) { - // This assembly was just resolved - if (enableTypeDefCache) { - var modules = resolvedAssembly.Modules; - int count = modules.Count; - for (int i = 0; i < count; i++) { - var module = modules[i]; - if (module is not null) - module.EnableTypeDefFindCache = true; - } - } - } - - bool inserted = false; - if (!cachedAssemblies.ContainsKey(key1)) { - cachedAssemblies.Add(key1, resolvedAssembly); - inserted = true; - } - if (!cachedAssemblies.ContainsKey(key2)) { - cachedAssemblies.Add(key2, resolvedAssembly); - inserted = true; - } - if (inserted || asm1 == resolvedAssembly || asm2 == resolvedAssembly) - return resolvedAssembly; - - // Dupe assembly. Don't insert it. - var dupeModule = resolvedAssembly.ManifestModule; - if (dupeModule is not null) - dupeModule.Dispose(); - return asm1 ?? asm2; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Add a module's assembly to the assembly cache - /// - /// The module whose assembly should be cached - /// 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 not null && AddToCache(module.Assembly); - - /// - /// Add an assembly to the assembly cache - /// - /// The assembly - /// true if is cached, false if it's not - /// 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 is null) - return false; - var asmKey = GetAssemblyNameKey(asm); -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (cachedAssemblies.TryGetValue(asmKey, out var cachedAsm) && cachedAsm is not null) - return asm == cachedAsm; - - if (enableTypeDefCache) - { - var modules = asm.Modules; - int count = modules.Count; - for (int i = 0; i < count; i++) - { - var module = modules[i]; - if (module is not null) - module.EnableTypeDefFindCache = true; - } - } - cachedAssemblies[asmKey] = asm; - return true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Removes a module's assembly from the cache - /// - /// The 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 bool Remove(ModuleDef module) => module is not null && Remove(module.Assembly); - - /// - /// Removes the assembly from the cache - /// - /// The assembly - /// 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 is null) - return false; - var asmKey = GetAssemblyNameKey(asm); -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return cachedAssemblies.Remove(asmKey); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Clears the cache and calls on each cached module. - /// Use to remove any assemblies you added yourself - /// using before calling this method if you don't want - /// them disposed. - /// - public void Clear() { - List asms; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - asms = new List(cachedAssemblies.Values); - cachedAssemblies.Clear(); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - foreach (var asm in asms) { - if (asm is null) - continue; - foreach (var mod in asm.Modules) - mod.Dispose(); - } - } - - /// - /// Gets the cached assemblies in this resolver. - /// - /// The cached assemblies. - 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= - return asmName.FullNameToken; - } - - AssemblyDef Resolve2(IAssembly assembly, ModuleDef sourceModule) { - if (cachedAssemblies.TryGetValue(GetAssemblyNameKey(assembly), out var resolvedAssembly)) - return resolvedAssembly; - - var moduleContext = defaultModuleContext; - 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 not null) - return resolvedAssembly; - - if (!findExactMatch) { - resolvedAssembly = FindClosestAssembly(assembly); - resolvedAssembly = FindClosestAssembly(assembly, resolvedAssembly, PreFindAssemblies(assembly, sourceModule, false), moduleContext); - resolvedAssembly = FindClosestAssembly(assembly, resolvedAssembly, FindAssemblies(assembly, sourceModule, false), moduleContext); - resolvedAssembly = FindClosestAssembly(assembly, resolvedAssembly, PostFindAssemblies(assembly, sourceModule, false), moduleContext); - } - - return resolvedAssembly; - } - - /// - /// Finds an assembly that exactly matches the requested assembly - /// - /// Assembly to find - /// Search paths or null if none - /// Module context - /// An instance or null if an exact match - /// couldn't be found. - AssemblyDef FindExactAssembly(IAssembly assembly, IEnumerable paths, ModuleContext moduleContext) { - if (paths is null) - return null; - var asmComparer = AssemblyNameComparer.CompareAll; - foreach (var path in paths) { - ModuleDefMD mod = null; - try { - mod = ModuleDefMD.Load(path, moduleContext); - var asm = mod.Assembly; - if (asm is not null && asmComparer.Equals(assembly, asm)) { - mod = null; - return asm; - } - } - catch { - } - finally { - if (mod is not null) - mod.Dispose(); - } - } - return null; - } - - /// - /// Finds the closest assembly from the already cached assemblies - /// - /// Assembly to find - /// The closest or null if none found - AssemblyDef FindClosestAssembly(IAssembly assembly) { - AssemblyDef closest = null; - var asmComparer = AssemblyNameComparer.CompareAll; - foreach (var kv in cachedAssemblies) { - var asm = kv.Value; - if (asm is null) - continue; - if (asmComparer.CompareClosest(assembly, closest, asm) == 1) - closest = asm; - } - return closest; - } - - AssemblyDef FindClosestAssembly(IAssembly assembly, AssemblyDef closest, IEnumerable paths, ModuleContext moduleContext) { - if (paths is null) - return closest; - var asmComparer = AssemblyNameComparer.CompareAll; - foreach (var path in paths) { - ModuleDefMD mod = null; - try { - mod = ModuleDefMD.Load(path, moduleContext); - var asm = mod.Assembly; - 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 not null) - closeMod.Dispose(); - } - closest = asm; - mod = null; - } - } - catch { - } - finally { - if (mod is not null) - mod.Dispose(); - } - } - - return closest; - } - - /// - /// Returns true if is inserted in - /// - /// Assembly to check - bool IsCached(AssemblyDef asm) { - if (asm is null) - return false; - return cachedAssemblies.TryGetValue(GetAssemblyNameKey(asm), out var cachedAsm) && - cachedAsm == asm; - } - - IEnumerable FindAssemblies2(IAssembly assembly, IEnumerable paths) { - if (paths is not null) { - var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - var exts = assembly.IsContentTypeWindowsRuntime ? winMDAssemblyExtensions : assemblyExtensions; - foreach (var ext in exts) { - foreach (var path in paths) { - string fullPath; - try { - fullPath = Path.Combine(path, asmSimpleName + ext); - } - catch (ArgumentException) { - // Invalid path chars - yield break; - } - if (File.Exists(fullPath)) - yield return fullPath; - } - } - } - } - - /// - /// Called before - /// - /// Assembly to find - /// The module that needs to resolve an assembly or null - /// We're trying to find an exact match - /// null or an enumerable of full paths to try - protected virtual IEnumerable PreFindAssemblies(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { - foreach (var path in FindAssemblies2(assembly, preSearchPaths)) - yield return path; - } - - /// - /// Called after (if it fails) - /// - /// Assembly to find - /// The module that needs to resolve an assembly or null - /// We're trying to find an exact match - /// null or an enumerable of full paths to try - protected virtual IEnumerable PostFindAssemblies(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { - foreach (var path in FindAssemblies2(assembly, postSearchPaths)) - yield return path; - } - - /// - /// Called after (if it fails) - /// - /// Assembly to find - /// The module that needs to resolve an assembly or null - /// We're trying to find an exact match - /// null or an enumerable of full paths to try - protected virtual IEnumerable FindAssemblies(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { - if (assembly.IsContentTypeWindowsRuntime) { - 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; - } - else { - if (UseGAC) { - foreach (var path in FindAssembliesGac(assembly, sourceModule, matchExactly)) - yield return path; - } - } - foreach (var path in FindAssembliesModuleSearchPaths(assembly, sourceModule, matchExactly)) - yield return path; - } - - IEnumerable FindAssembliesGac(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { - if (matchExactly) - return FindAssembliesGacExactly(assembly, sourceModule); - return FindAssembliesGacAny(assembly, 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 Framework 4 assembly) - foreach (var gacInfo in gacInfos) { - if (gacInfo.Version == version) - yield return gacInfo; - } - foreach (var gacInfo in gacInfos) { - if (gacInfo.Version != version) - yield return gacInfo; - } - } - - IEnumerable FindAssembliesGacExactly(IAssembly assembly, ModuleDef sourceModule) { - foreach (var gacInfo in GetGacInfos(sourceModule)) { - foreach (var path in FindAssembliesGacExactly(gacInfo, assembly, sourceModule)) - yield return path; - } - 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 not null) { - foreach (var dir in extraMonoPaths) { - string file; - try { - file = Path.Combine(dir, assembly.Name + ".dll"); - } - catch (ArgumentException) { - // Invalid path chars - break; - } - if (File.Exists(file)) - yield return file; - } - } - } - - IEnumerable FindAssembliesGacExactly(GacInfo gacInfo, IAssembly assembly, ModuleDef sourceModule) { - var pkt = PublicKeyBase.ToPublicKeyToken(assembly.PublicKeyOrToken); - 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); - 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); - 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)) - yield return pathName; - } - } - } - - IEnumerable FindAssembliesGacAny(IAssembly assembly, ModuleDef sourceModule) { - foreach (var gacInfo in GetGacInfos(sourceModule)) { - foreach (var path in FindAssembliesGacAny(gacInfo, assembly, sourceModule)) - yield return path; - } - 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 not null) { - var asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - foreach (var subDir in gacInfo.SubDirs) { - var baseDir = Path.Combine(gacInfo.Path, subDir); - 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)) - yield return pathName; - } - } - } - } - - IEnumerable GetDirs(string baseDir) { - if (!Directory.Exists(baseDir)) - return Array2.Empty(); - var dirs = new List(); - try { - foreach (var di in new DirectoryInfo(baseDir).GetDirectories()) - dirs.Add(di.FullName); - } - catch { - } - return dirs; - } - - IEnumerable FindAssembliesModuleSearchPaths(IAssembly assembly, ModuleDef sourceModule, bool matchExactly) { - string asmSimpleName = UTF8String.ToSystemStringOrEmpty(assembly.Name); - var searchPaths = GetSearchPaths(sourceModule); - var exts = assembly.IsContentTypeWindowsRuntime ? winMDAssemblyExtensions : assemblyExtensions; - foreach (var ext in exts) { - foreach (var path in searchPaths) { - for (int i = 0; i < 2; i++) { - string path2; - 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; - } - } - } - } - - /// - /// Gets all search paths to use for this module - /// - /// The module or null if unknown - /// A list of all search paths to use for this module - IEnumerable GetSearchPaths(ModuleDef module) { - var keyModule = module; - if (keyModule is null) - keyModule = nullModule; - if (moduleSearchPaths.TryGetValue(keyModule, out var searchPaths)) - return searchPaths; - moduleSearchPaths[keyModule] = searchPaths = new List(GetModuleSearchPaths(module)); - return searchPaths; - } - - /// - /// Gets all module search paths. This is usually empty unless its assembly has - /// a .config file specifying any additional private search paths in a - /// <probing/> element. - /// - /// The module or null if unknown - /// A list of search paths - protected virtual IEnumerable GetModuleSearchPaths(ModuleDef module) => GetModulePrivateSearchPaths(module); - - /// - /// Gets all private assembly search paths as found in the module's .config file. - /// - /// The module or null if unknown - /// A list of search paths - protected IEnumerable GetModulePrivateSearchPaths(ModuleDef module) { - if (module is null) - return Array2.Empty(); - var asm = module.Assembly; - if (asm is null) - return Array2.Empty(); - module = asm.ManifestModule; - if (module is null) - return Array2.Empty(); // Should never happen - - string baseDir = null; - try { - var imageName = module.Location; - if (imageName != string.Empty) { - 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 { - } - if (baseDir is not null) - return new List { baseDir }; - return Array2.Empty(); - } - - IEnumerable GetPrivatePaths(string baseDir, string configFileName) { - var searchPaths = new List(); - - try { - var dirName = Path.GetDirectoryName(Path.GetFullPath(configFileName)); - searchPaths.Add(dirName); - - using (var xmlStream = new FileStream(configFileName, FileMode.Open, FileAccess.Read, FileShare.Read)) { - var doc = new XmlDocument(); - doc.Load(XmlReader.Create(xmlStream)); - foreach (var tmp in doc.GetElementsByTagName("probing")) { - var probingElem = tmp as XmlElement; - if (probingElem is null) - continue; - var privatePath = probingElem.GetAttribute("privatePath"); - if (string.IsNullOrEmpty(privatePath)) - continue; - foreach (var tmp2 in privatePath.Split(';')) { - var path = tmp2.Trim(); - if (path == "") - continue; - var newPath = Path.GetFullPath(Path.Combine(dirName, path.Replace('\\', Path.DirectorySeparatorChar))); - if (Directory.Exists(newPath) && newPath.StartsWith(baseDir + Path.DirectorySeparatorChar)) - searchPaths.Add(newPath); - } - } - } - } - catch (ArgumentException) { - } - catch (IOException) { - } - catch (XmlException) { - } - - return searchPaths; - } - } -} diff --git a/Plugins/dnlib/DotNet/CallingConvention.cs b/Plugins/dnlib/DotNet/CallingConvention.cs deleted file mode 100644 index da2d655..0000000 --- a/Plugins/dnlib/DotNet/CallingConvention.cs +++ /dev/null @@ -1,48 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// See CorHdr.h/CorCallingConvention - /// - [Flags] - public enum CallingConvention : byte { - /// The managed calling convention - Default = 0x0, - /// - C = 0x1, - /// - StdCall = 0x2, - /// - ThisCall = 0x3, - /// - FastCall = 0x4, - /// - VarArg = 0x5, - /// - Field = 0x6, - /// - LocalSig = 0x7, - /// - Property = 0x8, - /// Unmanaged calling convention encoded as modopts - Unmanaged = 0x9, - /// generic method instantiation - GenericInst = 0xA, - /// used ONLY for 64bit vararg PInvoke calls - NativeVarArg = 0xB, - - /// Calling convention is bottom 4 bits - Mask = 0x0F, - - /// Generic method - Generic = 0x10, - /// Method needs a 'this' parameter - HasThis = 0x20, - /// 'this' parameter is the first arg if set (else it's hidden) - ExplicitThis = 0x40, - /// Used internally by the CLR - ReservedByCLR = 0x80, - } -} diff --git a/Plugins/dnlib/DotNet/CallingConventionSig.cs b/Plugins/dnlib/DotNet/CallingConventionSig.cs deleted file mode 100644 index 98c182d..0000000 --- a/Plugins/dnlib/DotNet/CallingConventionSig.cs +++ /dev/null @@ -1,1018 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -/* -All signature classes: - -CallingConventionSig - FieldSig - MethodBaseSig - MethodSig - PropertySig - LocalSig - GenericInstMethodSig -*/ - -namespace dnlib.DotNet { - /// - /// Base class for sigs with a calling convention - /// - public abstract class CallingConventionSig : IContainsGenericParameter { - /// - /// The calling convention - /// - protected CallingConvention callingConvention; - - byte[] extraData; - - /// - /// Gets/sets the extra data found after the signature - /// - public byte[] ExtraData { - get => extraData; - set => extraData = value; - } - - /// - /// Returns true if is set - /// - public bool IsDefault => (callingConvention & CallingConvention.Mask) == CallingConvention.Default; - - /// - /// Returns true if is set - /// - public bool IsC => (callingConvention & CallingConvention.Mask) == CallingConvention.C; - - /// - /// Returns true if is set - /// - public bool IsStdCall => (callingConvention & CallingConvention.Mask) == CallingConvention.StdCall; - - /// - /// Returns true if is set - /// - public bool IsThisCall => (callingConvention & CallingConvention.Mask) == CallingConvention.ThisCall; - - /// - /// Returns true if is set - /// - public bool IsFastCall => (callingConvention & CallingConvention.Mask) == CallingConvention.FastCall; - - /// - /// Returns true if is set - /// - public bool IsVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.VarArg; - - /// - /// Returns true if is set - /// - public bool IsField => (callingConvention & CallingConvention.Mask) == CallingConvention.Field; - - /// - /// Returns true if is set - /// - public bool IsLocalSig => (callingConvention & CallingConvention.Mask) == CallingConvention.LocalSig; - - /// - /// Returns true if is set - /// - public bool IsProperty => (callingConvention & CallingConvention.Mask) == CallingConvention.Property; - - /// - /// Returns true if is set - /// - public bool IsUnmanaged => (callingConvention & CallingConvention.Mask) == CallingConvention.Unmanaged; - - /// - /// Returns true if is set - /// - public bool IsGenericInst => (callingConvention & CallingConvention.Mask) == CallingConvention.GenericInst; - - /// - /// Returns true if is set - /// - public bool IsNativeVarArg => (callingConvention & CallingConvention.Mask) == CallingConvention.NativeVarArg; - - /// - /// Gets/sets the bit - /// - public bool Generic { - get => (callingConvention & CallingConvention.Generic) != 0; - set { - if (value) - callingConvention |= CallingConvention.Generic; - else - callingConvention &= ~CallingConvention.Generic; - } - } - - /// - /// Gets/sets the bit - /// - public bool HasThis { - get => (callingConvention & CallingConvention.HasThis) != 0; - set { - if (value) - callingConvention |= CallingConvention.HasThis; - else - callingConvention &= ~CallingConvention.HasThis; - } - } - - /// - /// Gets/sets the bit - /// - public bool ExplicitThis { - get => (callingConvention & CallingConvention.ExplicitThis) != 0; - set { - if (value) - callingConvention |= CallingConvention.ExplicitThis; - else - callingConvention &= ~CallingConvention.ExplicitThis; - } - } - - /// - /// Gets/sets the bit - /// - public bool ReservedByCLR { - get => (callingConvention & CallingConvention.ReservedByCLR) != 0; - set { - if (value) - callingConvention |= CallingConvention.ReservedByCLR; - else - callingConvention &= ~CallingConvention.ReservedByCLR; - } - } - - /// - /// true if there's an implicit this parameter - /// - public bool ImplicitThis => HasThis && !ExplicitThis; - - /// - /// true if this contains a - /// or a . - /// - public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - /// Default constructor - /// - protected CallingConventionSig() { - } - - /// - /// Constructor - /// - /// The calling convention - protected CallingConventionSig(CallingConvention callingConvention) => this.callingConvention = callingConvention; - - /// - /// Gets the calling convention - /// - public CallingConvention GetCallingConvention() => callingConvention; - } - - /// - /// A field signature - /// - public sealed class FieldSig : CallingConventionSig { - TypeSig type; - - /// - /// Gets/sets the field type - /// - public TypeSig Type { - get => type; - set => type = value; - } - - /// - /// Default constructor - /// - public FieldSig() => callingConvention = CallingConvention.Field; - - /// - /// Constructor - /// - /// Field type - public FieldSig(TypeSig type) { - callingConvention = CallingConvention.Field; - this.type = type; - } - - /// - /// Constructor - /// - /// Field type - /// The calling convention (must have Field set) - internal FieldSig(CallingConvention callingConvention, TypeSig type) { - this.callingConvention = callingConvention; - this.type = type; - } - - /// - /// Clone this - /// - public FieldSig Clone() => new FieldSig(callingConvention, type); - - /// - public override string ToString() => FullNameFactory.FullName(type, false, null, null, null, null); - } - - /// - /// Method sig base class - /// - public abstract class MethodBaseSig : CallingConventionSig { - /// - protected TypeSig retType; - /// - protected IList parameters; - /// - protected uint genParamCount; - /// - protected IList paramsAfterSentinel; - - /// - /// Gets/sets the calling convention - /// - public CallingConvention CallingConvention { - get => callingConvention; - set => callingConvention = value; - } - - /// - /// Gets/sets the return type - /// - public TypeSig RetType { - get => retType; - set => retType = value; - } - - /// - /// Gets the parameters. This is never null - /// - public IList Params => parameters; - - /// - /// Gets/sets the generic param count - /// - public uint GenParamCount { - get => genParamCount; - set => genParamCount = value; - } - - /// - /// Gets the parameters that are present after the sentinel. Note that this is null - /// if there's no sentinel. It can still be empty even if it's not null. - /// - public IList ParamsAfterSentinel { - get => paramsAfterSentinel; - set => paramsAfterSentinel = value; - } - } - - /// - /// A method signature - /// - public sealed class MethodSig : MethodBaseSig { - uint origToken; - - /// - /// Gets/sets the original token. It's set when reading calli instruction operands - /// and it's a hint to the module writer if it tries to re-use the same token. - /// - public uint OriginalToken { - get => origToken; - set => origToken = value; - } - - /// - /// Creates a static MethodSig - /// - /// Return type - 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) => new MethodSig(CallingConvention.Default, 0, retType, argType1); - - /// - /// Creates a static MethodSig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - public static MethodSig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default, 0, retType, argType1, argType2); - - /// - /// Creates a static MethodSig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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) => new MethodSig(CallingConvention.Default, 0, retType, argTypes); - - /// - /// Creates an instance MethodSig - /// - /// Return type - 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) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1); - - /// - /// Creates an instance MethodSig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - public static MethodSig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis, 0, retType, argType1, argType2); - - /// - /// Creates an instance MethodSig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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) => 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) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType); - - /// - /// Creates a static generic MethodSig - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - public static MethodSig CreateStaticGeneric(uint genParamCount, TypeSig retType, TypeSig argType1) => new MethodSig(CallingConvention.Default | CallingConvention.Generic, genParamCount, retType, argType1); - - /// - /// Creates a static generic MethodSig - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - 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 - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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 - /// - /// Number of generic parameters - /// Return type - /// Argument types - 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) => new MethodSig(CallingConvention.Default | CallingConvention.HasThis | CallingConvention.Generic, genParamCount, retType); - - /// - /// Creates an instance generic MethodSig - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - 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 - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - 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 - /// - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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 - /// - /// Number of generic parameters - /// Return type - /// Argument types - 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() => parameters = new List(); - - /// - /// Constructor - /// - /// Calling convention - public MethodSig(CallingConvention callingConvention) { - this.callingConvention = callingConvention; - parameters = new List(); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - public MethodSig(CallingConvention callingConvention, uint genParamCount) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - parameters = new List(); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List(); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Arg type #1 - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List { argType1 }; - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List { argType1, argType2 }; - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List { argType1, argType2, argType3 }; - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Argument types - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, params TypeSig[] argTypes) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List(argTypes); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Argument types - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List(argTypes); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Argument types - /// Parameters after sentinel - public MethodSig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes, IList paramsAfterSentinel) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List(argTypes); - this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); - } - - /// - /// Clone this - /// - public MethodSig Clone() => new MethodSig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); - - /// - public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); - } - - /// - /// A property signature - /// - public sealed class PropertySig : MethodBaseSig { - /// - /// Creates a static PropertySig - /// - /// Return type - 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) => new PropertySig(false, retType, argType1); - - /// - /// Creates a static PropertySig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - public static PropertySig CreateStatic(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(false, retType, argType1, argType2); - - /// - /// Creates a static PropertySig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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) => new PropertySig(false, retType, argTypes); - - /// - /// Creates an instance PropertySig - /// - /// Return type - 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) => new PropertySig(true, retType, argType1); - - /// - /// Creates an instance PropertySig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - public static PropertySig CreateInstance(TypeSig retType, TypeSig argType1, TypeSig argType2) => new PropertySig(true, retType, argType1, argType2); - - /// - /// Creates an instance PropertySig - /// - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - 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) => new PropertySig(true, retType, argTypes); - - /// - /// Default constructor - /// - public PropertySig() { - callingConvention = CallingConvention.Property; - parameters = new List(); - } - - /// - /// Constructor - /// - /// Calling convention (must have Property set) - internal PropertySig(CallingConvention callingConvention) { - this.callingConvention = callingConvention; - parameters = new List(); - } - - /// - /// Constructor - /// - /// true if instance, false if static - public PropertySig(bool hasThis) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - parameters = new List(); - } - - /// - /// Constructor - /// - /// true if instance, false if static - /// Return type - public PropertySig(bool hasThis, TypeSig retType) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.retType = retType; - parameters = new List(); - } - - /// - /// Constructor - /// - /// true if instance, false if static - /// Return type - /// Arg type #1 - public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.retType = retType; - parameters = new List { argType1 }; - } - - /// - /// Constructor - /// - /// true if instance, false if static - /// Return type - /// Arg type #1 - /// Arg type #2 - public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.retType = retType; - parameters = new List { argType1, argType2 }; - } - - /// - /// Constructor - /// - /// true if instance, false if static - /// Return type - /// Arg type #1 - /// Arg type #2 - /// Arg type #3 - public PropertySig(bool hasThis, TypeSig retType, TypeSig argType1, TypeSig argType2, TypeSig argType3) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.retType = retType; - parameters = new List { argType1, argType2, argType3 }; - } - - /// - /// Constructor - /// - /// true if instance, false if static - /// Return type - /// Argument types - public PropertySig(bool hasThis, TypeSig retType, params TypeSig[] argTypes) { - callingConvention = CallingConvention.Property | (hasThis ? CallingConvention.HasThis : 0); - this.retType = retType; - parameters = new List(argTypes); - } - - /// - /// Constructor - /// - /// Calling convention - /// Number of generic parameters - /// Return type - /// Argument types - /// Parameters after sentinel - internal PropertySig(CallingConvention callingConvention, uint genParamCount, TypeSig retType, IList argTypes, IList paramsAfterSentinel) { - this.callingConvention = callingConvention; - this.genParamCount = genParamCount; - this.retType = retType; - parameters = new List(argTypes); - this.paramsAfterSentinel = paramsAfterSentinel is null ? null : new List(paramsAfterSentinel); - } - - /// - /// Clone this - /// - public PropertySig Clone() => new PropertySig(callingConvention, genParamCount, retType, parameters, paramsAfterSentinel); - - /// - public override string ToString() => FullNameFactory.MethodBaseSigFullName(this, null); - } - - /// - /// A local variables signature - /// - public sealed class LocalSig : CallingConventionSig { - readonly IList locals; - - /// - /// All local types. This is never null. - /// - public IList Locals => locals; - - /// - /// Default constructor - /// - public LocalSig() { - callingConvention = CallingConvention.LocalSig; - locals = new List(); - } - - /// - /// Constructor - /// - /// Calling convention (must have LocalSig set) - /// Number of locals - internal LocalSig(CallingConvention callingConvention, uint count) { - this.callingConvention = callingConvention; - locals = new List((int)count); - } - - /// - /// Constructor - /// - /// Local type #1 - public LocalSig(TypeSig local1) { - callingConvention = CallingConvention.LocalSig; - locals = new List { local1 }; - } - - /// - /// Constructor - /// - /// Local type #1 - /// Local type #2 - public LocalSig(TypeSig local1, TypeSig local2) { - callingConvention = CallingConvention.LocalSig; - locals = new List { local1, local2 }; - } - - /// - /// Constructor - /// - /// Local type #1 - /// Local type #2 - /// Local type #3 - public LocalSig(TypeSig local1, TypeSig local2, TypeSig local3) { - callingConvention = CallingConvention.LocalSig; - locals = new List { local1, local2, local3 }; - } - - /// - /// Constructor - /// - /// All locals - public LocalSig(params TypeSig[] locals) { - callingConvention = CallingConvention.LocalSig; - this.locals = new List(locals); - } - - /// - /// Constructor - /// - /// All locals - public LocalSig(IList locals) { - callingConvention = CallingConvention.LocalSig; - this.locals = new List(locals); - } - - /// - /// Constructor - /// - /// All locals (this instance now owns it) - /// Dummy - internal LocalSig(IList locals, bool dummy) { - callingConvention = CallingConvention.LocalSig; - this.locals = locals; - } - - /// - /// Clone this - /// - public LocalSig Clone() => new LocalSig(locals); - } - - /// - /// An instantiated generic method signature - /// - public sealed class GenericInstMethodSig : CallingConventionSig { - readonly IList genericArgs; - - /// - /// Gets the generic arguments (must be instantiated types, i.e., closed types) - /// - public IList GenericArguments => genericArgs; - - /// - /// Default constructor - /// - public GenericInstMethodSig() { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List(); - } - - /// - /// Constructor - /// - /// Calling convention (must have GenericInst set) - /// Number of generic args - internal GenericInstMethodSig(CallingConvention callingConvention, uint size) { - this.callingConvention = callingConvention; - genericArgs = new List((int)size); - } - - /// - /// Constructor - /// - /// Generic arg #1 - public GenericInstMethodSig(TypeSig arg1) { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List { arg1 }; - } - - /// - /// Constructor - /// - /// Generic arg #1 - /// Generic arg #2 - public GenericInstMethodSig(TypeSig arg1, TypeSig arg2) { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List { arg1, arg2 }; - } - - /// - /// Constructor - /// - /// Generic arg #1 - /// Generic arg #2 - /// Generic arg #3 - public GenericInstMethodSig(TypeSig arg1, TypeSig arg2, TypeSig arg3) { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List { arg1, arg2, arg3 }; - } - - /// - /// Constructor - /// - /// Generic args - public GenericInstMethodSig(params TypeSig[] args) { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List(args); - } - - /// - /// Constructor - /// - /// Generic args - public GenericInstMethodSig(IList args) { - callingConvention = CallingConvention.GenericInst; - genericArgs = new List(args); - } - - /// - /// Clone this - /// - public GenericInstMethodSig Clone() => new GenericInstMethodSig(genericArgs); - } - - public static partial class Extensions { - /// - /// Gets the field type - /// - /// this - /// Field type or null if none - 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) => sig?.RetType; - - /// - /// Gets the parameters - /// - /// this - /// The parameters - public static IList GetParams(this MethodBaseSig sig) => sig?.Params ?? new List(); - - /// - /// Gets the parameter count - /// - /// this - /// Parameter 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) => sig?.GenParamCount ?? 0; - - /// - /// Gets the parameters after the sentinel - /// - /// this - /// Parameters after sentinel or null if none - public static IList GetParamsAfterSentinel(this MethodBaseSig sig) => sig?.ParamsAfterSentinel; - - /// - /// Gets the locals - /// - /// this - /// All locals - public static IList GetLocals(this LocalSig sig) => sig?.Locals ?? new List(); - - /// - /// Gets the generic arguments - /// - /// this - /// All generic arguments - public static IList GetGenericArguments(this GenericInstMethodSig sig) => sig?.GenericArguments ?? new List(); - - /// - /// Gets the property - /// - /// this - /// The type's property or - /// false if input isnull - public static bool GetIsDefault(this CallingConventionSig sig) => sig?.IsDefault ?? false; - } -} diff --git a/Plugins/dnlib/DotNet/ClassLayout.cs b/Plugins/dnlib/DotNet/ClassLayout.cs deleted file mode 100644 index e11c698..0000000 --- a/Plugins/dnlib/DotNet/ClassLayout.cs +++ /dev/null @@ -1,99 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the ClassLayout table - /// - public abstract class ClassLayout : IMDTokenProvider { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.ClassLayout, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - /// From column ClassLayout.PackingSize - /// - public ushort PackingSize { - get => packingSize; - set => packingSize = value; - } - /// - protected ushort packingSize; - - /// - /// From column ClassLayout.ClassSize - /// - public uint ClassSize { - get => classSize; - set => classSize = value; - } - /// - protected uint classSize; - } - - /// - /// A ClassLayout row created by the user and not present in the original .NET file - /// - public class ClassLayoutUser : ClassLayout { - /// - /// Default constructor - /// - public ClassLayoutUser() { - } - - /// - /// Constructor - /// - /// PackingSize - /// ClassSize - public ClassLayoutUser(ushort packingSize, uint classSize) { - this.packingSize = packingSize; - this.classSize = classSize; - } - } - - /// - /// Created from a row in the ClassLayout table - /// - sealed class ClassLayoutMD : ClassLayout, IMDTokenProviderMD { - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - /// Constructor - /// - /// The module which contains this ClassLayout row - /// Row ID - /// If is null - /// If is invalid - public ClassLayoutMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ClassLayoutTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"ClassLayout rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - bool b = readerModule.TablesStream.TryReadClassLayoutRow(origRid, out var row); - Debug.Assert(b); - classSize = row.ClassSize; - packingSize = row.PackingSize; - } - } -} diff --git a/Plugins/dnlib/DotNet/Constant.cs b/Plugins/dnlib/DotNet/Constant.cs deleted file mode 100644 index 9d10006..0000000 --- a/Plugins/dnlib/DotNet/Constant.cs +++ /dev/null @@ -1,204 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.DotNet.MD; -using dnlib.IO; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Constant table - /// - public abstract class Constant : IMDTokenProvider { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.Constant, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - /// From column Constant.Type - /// - public ElementType Type { - get => type; - set => type = value; - } - /// - protected ElementType type; - - /// - /// From column Constant.Value - /// - public object Value { - get => value; - set => this.value = value; - } - /// - protected object value; - } - - /// - /// A Constant row created by the user and not present in the original .NET file - /// - public class ConstantUser : Constant { - /// - /// Default constructor - /// - public ConstantUser() { - } - - /// - /// Constructor - /// - /// Value - public ConstantUser(object value) { - type = GetElementType(value); - this.value = value; - } - - /// - /// Constructor - /// - /// Value - /// Type - public ConstantUser(object value, ElementType type) { - this.type = type; - this.value = value; - } - - static ElementType GetElementType(object value) { - if (value is null) - return ElementType.Class; - 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, - }; - } - } - - /// - /// Created from a row in the Constant table - /// - sealed class ConstantMD : Constant, IMDTokenProviderMD { - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - /// Constructor - /// - /// The module which contains this Constant row - /// Row ID - /// If is null - /// If is invalid - public ConstantMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ConstantTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Constant rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - bool b = readerModule.TablesStream.TryReadConstantRow(origRid, out var row); - Debug.Assert(b); - type = (ElementType)row.Type; - var reader = readerModule.BlobStream.CreateReader(row.Value); - value = GetValue(type, ref reader); - } - - static object GetValue(ElementType etype, ref DataReader reader) { - switch (etype) { - case ElementType.Boolean: - if (reader.Length < 1) - return false; - return reader.ReadBoolean(); - - case ElementType.Char: - if (reader.Length < 2) - return (char)0; - return reader.ReadChar(); - - case ElementType.I1: - if (reader.Length < 1) - return (sbyte)0; - return reader.ReadSByte(); - - case ElementType.U1: - if (reader.Length < 1) - return (byte)0; - return reader.ReadByte(); - - case ElementType.I2: - if (reader.Length < 2) - return (short)0; - return reader.ReadInt16(); - - case ElementType.U2: - if (reader.Length < 2) - return (ushort)0; - return reader.ReadUInt16(); - - case ElementType.I4: - if (reader.Length < 4) - return (int)0; - return reader.ReadInt32(); - - case ElementType.U4: - if (reader.Length < 4) - return (uint)0; - return reader.ReadUInt32(); - - case ElementType.I8: - if (reader.Length < 8) - return (long)0; - return reader.ReadInt64(); - - case ElementType.U8: - if (reader.Length < 8) - return (ulong)0; - return reader.ReadUInt64(); - - case ElementType.R4: - if (reader.Length < 4) - return (float)0; - return reader.ReadSingle(); - - case ElementType.R8: - if (reader.Length < 8) - return (double)0; - return reader.ReadDouble(); - - case ElementType.String: - return reader.ReadUtf16String((int)(reader.BytesLeft / 2)); - - case ElementType.Class: - return null; - - default: - return null; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/CorLibTypes.cs b/Plugins/dnlib/DotNet/CorLibTypes.cs deleted file mode 100644 index 8a2f598..0000000 --- a/Plugins/dnlib/DotNet/CorLibTypes.cs +++ /dev/null @@ -1,143 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Default implementation of - /// - public sealed class CorLibTypes : ICorLibTypes { - readonly ModuleDef module; - CorLibTypeSig typeVoid; - CorLibTypeSig typeBoolean; - CorLibTypeSig typeChar; - CorLibTypeSig typeSByte; - CorLibTypeSig typeByte; - CorLibTypeSig typeInt16; - CorLibTypeSig typeUInt16; - CorLibTypeSig typeInt32; - CorLibTypeSig typeUInt32; - CorLibTypeSig typeInt64; - CorLibTypeSig typeUInt64; - CorLibTypeSig typeSingle; - CorLibTypeSig typeDouble; - CorLibTypeSig typeString; - CorLibTypeSig typeTypedReference; - CorLibTypeSig typeIntPtr; - CorLibTypeSig typeUIntPtr; - CorLibTypeSig typeObject; - readonly AssemblyRef corLibAssemblyRef; - - /// - public CorLibTypeSig Void => typeVoid; - - /// - public CorLibTypeSig Boolean => typeBoolean; - - /// - public CorLibTypeSig Char => typeChar; - - /// - public CorLibTypeSig SByte => typeSByte; - - /// - public CorLibTypeSig Byte => typeByte; - - /// - public CorLibTypeSig Int16 => typeInt16; - - /// - public CorLibTypeSig UInt16 => typeUInt16; - - /// - public CorLibTypeSig Int32 => typeInt32; - - /// - public CorLibTypeSig UInt32 => typeUInt32; - - /// - public CorLibTypeSig Int64 => typeInt64; - - /// - public CorLibTypeSig UInt64 => typeUInt64; - - /// - public CorLibTypeSig Single => typeSingle; - - /// - public CorLibTypeSig Double => typeDouble; - - /// - public CorLibTypeSig String => typeString; - - /// - public CorLibTypeSig TypedReference => typeTypedReference; - - /// - public CorLibTypeSig IntPtr => typeIntPtr; - - /// - public CorLibTypeSig UIntPtr => typeUIntPtr; - - /// - public CorLibTypeSig Object => typeObject; - - /// - public AssemblyRef AssemblyRef => corLibAssemblyRef; - - /// - /// Constructor - /// - /// The owner module - public CorLibTypes(ModuleDef module) - : this(module, null) { - } - - /// - /// Constructor - /// - /// The owner module - /// Corlib assembly reference or null if a default - /// assembly reference should be created - public CorLibTypes(ModuleDef module, AssemblyRef corLibAssemblyRef) { - this.module = module; - this.corLibAssemblyRef = corLibAssemblyRef ?? CreateCorLibAssemblyRef(); - Initialize(); - } - - AssemblyRef CreateCorLibAssemblyRef() => module.UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); - - void Initialize() { - bool isCorLib = module.Assembly.IsCorLib(); - typeVoid = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Void"), ElementType.Void); - typeBoolean = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Boolean"), ElementType.Boolean); - typeChar = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Char"), ElementType.Char); - typeSByte = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "SByte"), ElementType.I1); - typeByte = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Byte"), ElementType.U1); - typeInt16 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Int16"), ElementType.I2); - typeUInt16 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "UInt16"), ElementType.U2); - typeInt32 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Int32"), ElementType.I4); - typeUInt32 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "UInt32"), ElementType.U4); - typeInt64 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Int64"), ElementType.I8); - typeUInt64 = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "UInt64"), ElementType.U8); - typeSingle = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Single"), ElementType.R4); - typeDouble = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Double"), ElementType.R8); - typeString = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "String"), ElementType.String); - typeTypedReference = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "TypedReference"), ElementType.TypedByRef); - typeIntPtr = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "IntPtr"), ElementType.I); - typeUIntPtr = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "UIntPtr"), ElementType.U); - typeObject = new CorLibTypeSig(CreateCorLibTypeRef(isCorLib, "Object"), ElementType.Object); - } - - ITypeDefOrRef CreateCorLibTypeRef(bool isCorLib, string name) { - var tr = new TypeRefUser(module, "System", name, corLibAssemblyRef); - if (isCorLib) { - var td = module.Find(tr); - if (td is not null) - return td; - } - return module.UpdateRowId(tr); - } - - /// - public TypeRef GetTypeRef(string @namespace, string name) => module.UpdateRowId(new TypeRefUser(module, @namespace, name, corLibAssemblyRef)); - } -} diff --git a/Plugins/dnlib/DotNet/CpuArch.cs b/Plugins/dnlib/DotNet/CpuArch.cs deleted file mode 100644 index 2e0c27a..0000000 --- a/Plugins/dnlib/DotNet/CpuArch.cs +++ /dev/null @@ -1,427 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.DotNet.Writer; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet { - enum StubType { - Export, - EntryPoint, - } - - abstract class CpuArch { - // 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 - /// - /// 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) { - 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: - case Machine.I386_Native_Sun: - 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: - case Machine.AMD64_Native_Sun: - 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: - case Machine.ARMNT_Native_Sun: - 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: - case Machine.ARM64_Native_Sun: - //TODO: Support ARM64 - goto default; - - default: - cpuArch = null; - return false; - } - } - - /// - /// 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(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); - - /// - /// 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, DataWriter 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(ref DataReader 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, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { - switch (stubType) { - case StubType.Export: - case StubType.EntryPoint: - writer.WriteUInt16(0);// padding - writer.WriteUInt16(0x25FF); - writer.WriteUInt32((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(ref DataReader 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, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { - switch (stubType) { - case StubType.Export: - case StubType.EntryPoint: - writer.WriteUInt16(0);// padding - writer.WriteUInt16(0xA148); - writer.WriteUInt64(imageBase + managedFuncRva); - writer.WriteUInt16(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(ref DataReader 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 = (uint)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, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { - switch (stubType) { - case StubType.Export: - case StubType.EntryPoint: - 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(); - } - } - } - - 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(ref DataReader 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, DataWriter writer, ulong imageBase, uint stubRva, uint managedFuncRva) { - switch (stubType) { - case StubType.Export: - case StubType.EntryPoint: - writer.WriteUInt32(0xF000F8DF); - writer.WriteUInt32((uint)imageBase + managedFuncRva); - break; - default: - throw new ArgumentOutOfRangeException(); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/CustomAttribute.cs b/Plugins/dnlib/DotNet/CustomAttribute.cs deleted file mode 100644 index 36367e9..0000000 --- a/Plugins/dnlib/DotNet/CustomAttribute.cs +++ /dev/null @@ -1,462 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// A custom attribute - /// - public sealed class CustomAttribute : ICustomAttribute { - ICustomAttributeType ctor; - byte[] rawData; - readonly IList arguments; - readonly IList namedArguments; - uint caBlobOffset; - - /// - /// Gets/sets the custom attribute constructor - /// - public ICustomAttributeType Constructor { - get => ctor; - set => ctor = value; - } - - /// - /// Gets the attribute type - /// - public ITypeDefOrRef AttributeType => ctor?.DeclaringType; - - /// - /// Gets the full name of the attribute type - /// - public string TypeFullName { - get { - if (ctor is MemberRef mrCtor) - return mrCtor.GetDeclaringTypeFullName() ?? string.Empty; - - if (ctor is MethodDef mdCtor) { - var declType = mdCtor.DeclaringType; - if (declType is not null) - return declType.FullName; - } - - 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 - /// - public bool IsRawBlob => rawData is not null; - - /// - /// Gets the raw custom attribute blob or null if the CA was successfully parsed. - /// - public byte[] RawData => rawData; - - /// - /// Gets all constructor arguments - /// - public IList ConstructorArguments => arguments; - - /// - /// true if is not empty - /// - public bool HasConstructorArguments => arguments.Count > 0; - - /// - /// Gets all named arguments (field and property values) - /// - public IList NamedArguments => namedArguments; - - /// - /// true if is not empty - /// - public bool HasNamedArguments => namedArguments.Count > 0; - - /// - /// Gets all s that are field arguments - /// - public IEnumerable Fields { - get { - 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; - } - } - } - - /// - /// Gets all s that are property arguments - /// - public IEnumerable Properties { - get { - 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; - } - } - } - - /// - /// Gets the #Blob offset or 0 if unknown - /// - public uint BlobOffset => caBlobOffset; - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Raw custom attribute blob - public CustomAttribute(ICustomAttributeType ctor, byte[] rawData) - : this(ctor, null, null, 0) => this.rawData = rawData; - - /// - /// Constructor - /// - /// Custom attribute constructor - public CustomAttribute(ICustomAttributeType ctor) - : this(ctor, null, null, 0) { - } - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Constructor arguments or null if none - public CustomAttribute(ICustomAttributeType ctor, IEnumerable arguments) - : this(ctor, arguments, null) { - } - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Named arguments or null if none - public CustomAttribute(ICustomAttributeType ctor, IEnumerable namedArguments) - : this(ctor, null, namedArguments) { - } - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Constructor arguments or null if none - /// Named arguments or null if none - public CustomAttribute(ICustomAttributeType ctor, IEnumerable arguments, IEnumerable namedArguments) - : this(ctor, arguments, namedArguments, 0) { - } - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Constructor arguments or null if none - /// Named arguments or null if none - /// Original custom attribute #Blob offset or 0 - public CustomAttribute(ICustomAttributeType ctor, IEnumerable arguments, IEnumerable namedArguments, uint caBlobOffset) { - this.ctor = ctor; - this.arguments = arguments is null ? new List() : new List(arguments); - this.namedArguments = namedArguments is null ? new List() : new List(namedArguments); - this.caBlobOffset = caBlobOffset; - } - - /// - /// Constructor - /// - /// Custom attribute constructor - /// Constructor arguments. The list is now owned by this instance. - /// Named arguments. The list is now owned by this instance. - /// Original custom attribute #Blob offset or 0 - internal CustomAttribute(ICustomAttributeType ctor, List arguments, List namedArguments, uint caBlobOffset) { - this.ctor = ctor; - this.arguments = arguments ?? new List(); - this.namedArguments = namedArguments ?? new List(); - this.caBlobOffset = caBlobOffset; - } - - /// - /// Gets the field named - /// - /// Name of field - /// A instance or null if not found - 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) => GetNamedArgument(name, true); - - /// - /// Gets the property named - /// - /// Name of property - /// A instance or null if not found - 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) => GetNamedArgument(name, false); - - /// - /// Gets the property/field named - /// - /// Name of property/field - /// 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) { - 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; - } - return null; - } - - /// - /// Gets the property/field named - /// - /// Name of property/field - /// 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) { - 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; - } - return null; - } - - /// - public override string ToString() => TypeFullName; - } - - /// - /// A custom attribute constructor argument - /// - public struct CAArgument : ICloneable { - TypeSig type; - object value; - - /// - /// Gets/sets the argument type - /// - public TypeSig Type { - readonly get => type; - set => type = value; - } - - /// - /// Gets/sets the argument value - /// - public object Value { - readonly get => value; - set => this.value = value; - } - - /// - /// Constructor - /// - /// Argument type - public CAArgument(TypeSig type) { - this.type = type; - value = null; - } - - /// - /// Constructor - /// - /// Argument type - /// Argument value - public CAArgument(TypeSig type, object value) { - this.type = type; - this.value = value; - } - - readonly object ICloneable.Clone() => Clone(); - - /// - /// Clones this instance and any s and s - /// referenced from this instance. - /// - /// - public readonly CAArgument Clone() { - var value = this.value; - if (value is CAArgument) - value = ((CAArgument)value).Clone(); - else if (value is IList args) { - var newArgs = new List(args.Count); - 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); - } - - /// - public override readonly string ToString() => $"{value ?? "null"} ({type})"; - } - - /// - /// A custom attribute field/property argument - /// - public sealed class CANamedArgument : ICloneable { - bool isField; - TypeSig type; - UTF8String name; - CAArgument argument; - - /// - /// true if it's a field - /// - public bool IsField { - get => isField; - set => isField = value; - } - - /// - /// true if it's a property - /// - public bool IsProperty { - get => !isField; - set => isField = !value; - } - - /// - /// Gets/sets the field/property type - /// - public TypeSig Type { - get => type; - set => type = value; - } - - /// - /// Gets/sets the property/field name - /// - public UTF8String Name { - get => name; - set => name = value; - } - - /// - /// Gets/sets the argument - /// - public CAArgument Argument { - get => argument; - set => argument = value; - } - - /// - /// Gets/sets the argument type - /// - public TypeSig ArgumentType { - get => argument.Type; - set => argument.Type = value; - } - - /// - /// Gets/sets the argument value - /// - public object Value { - get => argument.Value; - set => argument.Value = value; - } - - /// - /// Default constructor - /// - public CANamedArgument() { - } - - /// - /// Constructor - /// - /// true if field, false if property - public CANamedArgument(bool isField) => this.isField = isField; - - /// - /// Constructor - /// - /// true if field, false if property - /// Field/property type - public CANamedArgument(bool isField, TypeSig type) { - this.isField = isField; - this.type = type; - } - - /// - /// Constructor - /// - /// true if field, false if property - /// Field/property type - /// Name of field/property - public CANamedArgument(bool isField, TypeSig type, UTF8String name) { - this.isField = isField; - this.type = type; - this.name = name; - } - - /// - /// Constructor - /// - /// true if field, false if property - /// Field/property type - /// Name of field/property - /// Field/property argument - public CANamedArgument(bool isField, TypeSig type, UTF8String name, CAArgument argument) { - this.isField = isField; - this.type = type; - this.name = name; - this.argument = argument; - } - - object ICloneable.Clone() => Clone(); - - /// - /// Clones this instance and any s referenced from this instance. - /// - /// - public CANamedArgument Clone() => new CANamedArgument(isField, type, name, argument.Clone()); - - /// - public override string ToString() => $"({(isField ? "field" : "property")}) {type} {name} = {Value ?? "null"} ({ArgumentType})"; - } -} diff --git a/Plugins/dnlib/DotNet/CustomAttributeCollection.cs b/Plugins/dnlib/DotNet/CustomAttributeCollection.cs deleted file mode 100644 index 07fba46..0000000 --- a/Plugins/dnlib/DotNet/CustomAttributeCollection.cs +++ /dev/null @@ -1,125 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.Utils; -using System; - -namespace dnlib.DotNet { - /// - /// Stores s - /// - public class CustomAttributeCollection : LazyList { - /// - /// Default constructor - /// - public CustomAttributeCollection() { - } - - /// - /// Constructor - /// - /// Initial length of the list - /// Context passed to - /// Delegate instance that returns original values - public CustomAttributeCollection(int length, object context, Func readOriginalValue) - : base(length, context, readOriginalValue) { - } - - /// - /// Checks whether a custom attribute is present - /// - /// Full name of custom attribute type - /// true if the custom attribute type is present, false otherwise - public bool IsDefined(string fullName) => Find(fullName) is not null; - - /// - /// Removes all custom attributes of a certain type - /// - /// 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--) { - var ca = this[i]; - if (ca is not null && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) - RemoveAt(i); - } - } - - /// - /// Finds a custom attribute - /// - /// 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 && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) - return ca; - } - - return null; - } - - /// - /// Finds all custom attributes of a certain type - /// - /// 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 && fullName.EndsWith(ca.TypeName, StringComparison.Ordinal) && ca.TypeFullName == fullName) - yield return ca; - } - } - - /// - /// Finds a custom attribute - /// - /// Custom attribute type - /// The first found or null if none found - public CustomAttribute Find(IType attrType) => Find(attrType, 0); - - /// - /// Finds a custom attribute - /// - /// Custom attribute type - /// Attribute type comparison flags - /// The first found or null if none found - public CustomAttribute Find(IType attrType, SigComparerOptions options) { - var comparer = new SigComparer(options); - foreach (var ca in this) { - if (comparer.Equals(ca.AttributeType, attrType)) - return ca; - } - return null; - } - - /// - /// Finds all custom attributes of a certain type - /// - /// Custom attribute type - /// All s of the requested type - public IEnumerable FindAll(IType attrType) => FindAll(attrType, 0); - - /// - /// Finds all custom attributes of a certain type - /// - /// Custom attribute type - /// Attribute type comparison flags - /// All s of the requested type - public IEnumerable FindAll(IType attrType, SigComparerOptions options) { - var comparer = new SigComparer(options); - foreach (var ca in this) { - if (comparer.Equals(ca.AttributeType, attrType)) - yield return ca; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/CustomAttributeReader.cs b/Plugins/dnlib/DotNet/CustomAttributeReader.cs deleted file mode 100644 index 2d35086..0000000 --- a/Plugins/dnlib/DotNet/CustomAttributeReader.cs +++ /dev/null @@ -1,599 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using dnlib.IO; - -namespace dnlib.DotNet { - /// - /// Searches for a type according to custom attribute search rules: first try the - /// current assembly, and if that fails, try mscorlib - /// - sealed class CAAssemblyRefFinder : IAssemblyRefFinder { - readonly ModuleDef module; - - /// - /// Constructor - /// - /// The module to search first - public CAAssemblyRefFinder(ModuleDef module) => this.module = module; - - /// - public AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { - var modAsm = module.Assembly; - 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 not null) - return AssemblyRef.CurrentAssembly; - - var corLibAsm = module.Context.AssemblyResolver.Resolve(module.CorLibTypes.AssemblyRef, module); - if (corLibAsm is not null) { - var type = corLibAsm.Find(nonNestedTypeRef); - if (type is not null) - return module.CorLibTypes.AssemblyRef; - } - if (nonNestedTypeRef.Namespace == "System" || nonNestedTypeRef.Namespace.StartsWith("System.")) - return module.CorLibTypes.AssemblyRef; - - if (modAsm is not null) - return module.UpdateRowId(new AssemblyRefUser(modAsm)); - return AssemblyRef.CurrentAssembly; - } - } - - /// - /// Thrown by CustomAttributeReader when it fails to parse a custom attribute blob - /// - [Serializable] - public class CABlobParserException : Exception { - /// - /// Default constructor - /// - public CABlobParserException() { - } - - /// - /// Constructor - /// - /// Error message - public CABlobParserException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Error message - /// Other exception - public CABlobParserException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected CABlobParserException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Reads custom attributes from the #Blob stream - /// - public struct CustomAttributeReader { - readonly ModuleDef module; - DataReader reader; - readonly uint caBlobOffset; - readonly GenericParamContext gpContext; - GenericArguments genericArguments; - RecursionCounter recursionCounter; - bool verifyReadAllBytes; - - /// - /// Reads a custom attribute - /// - /// Reader module - /// Custom attribute constructor - /// Offset of custom attribute in the #Blob stream - /// A new instance - public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeType ctor, uint offset) => Read(readerModule, ctor, offset, new GenericParamContext()); - - /// - /// Reads a custom attribute - /// - /// Reader module - /// Custom attribute constructor - /// Offset of custom attribute in the #Blob stream - /// Generic parameter context - /// A new instance - public static CustomAttribute Read(ModuleDefMD readerModule, ICustomAttributeType ctor, uint offset, GenericParamContext gpContext) { - var caReader = new CustomAttributeReader(readerModule, offset, gpContext); - try { - if (ctor is null) - return caReader.CreateRaw(ctor); - return caReader.Read(ctor); - } - catch (CABlobParserException) { - return caReader.CreateRaw(ctor); - } - catch (IOException) { - return caReader.CreateRaw(ctor); - } - } - - CustomAttribute CreateRaw(ICustomAttributeType ctor) => new CustomAttribute(ctor, GetRawBlob()); - - /// - /// Reads a custom attribute - /// - /// Owner module - /// CA blob - /// Custom attribute constructor - /// A new instance - public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor) => - Read(module, ByteArrayDataReaderFactory.CreateReader(caBlob), ctor, new GenericParamContext()); - - /// - /// Reads a custom attribute - /// - /// Owner module - /// A reader positioned at the the first byte of the CA blob - /// Custom attribute constructor - /// A new instance - public static CustomAttribute Read(ModuleDef module, DataReader reader, ICustomAttributeType ctor) => - Read(module, ref reader, ctor, new GenericParamContext()); - - /// - /// Reads a custom attribute - /// - /// Owner module - /// CA blob - /// Custom attribute constructor - /// Generic parameter context - /// A new instance - public static CustomAttribute Read(ModuleDef module, byte[] caBlob, ICustomAttributeType ctor, GenericParamContext gpContext) => - Read(module, ByteArrayDataReaderFactory.CreateReader(caBlob), ctor, gpContext); - - /// - /// Reads a custom attribute - /// - /// Owner module - /// A stream positioned at the the first byte of the CA blob - /// Custom attribute constructor - /// Generic parameter context - /// A new instance - public static CustomAttribute Read(ModuleDef module, DataReader reader, ICustomAttributeType ctor, GenericParamContext gpContext) => - Read(module, ref reader, ctor, gpContext); - - /// - /// Reads a custom attribute - /// - /// Owner module - /// A stream positioned at the the first byte of the CA blob - /// Custom attribute constructor - /// Generic parameter context - /// A new instance - static CustomAttribute Read(ModuleDef module, ref DataReader reader, ICustomAttributeType ctor, GenericParamContext gpContext) { - var caReader = new CustomAttributeReader(module, ref reader, gpContext); - CustomAttribute ca; - try { - if (ctor is null) - ca = caReader.CreateRaw(ctor); - else - ca = caReader.Read(ctor); - } - catch (CABlobParserException) { - ca = caReader.CreateRaw(ctor); - } - catch (IOException) { - ca = caReader.CreateRaw(ctor); - } - return ca; - } - - /// - /// Reads custom attribute named arguments - /// - /// Owner module - /// A reader positioned at the the first byte of the CA blob - /// Number of named arguments to read from - /// Generic parameter context - /// A list of s or null if some error - /// occurred. - internal static List ReadNamedArguments(ModuleDef module, ref DataReader reader, int numNamedArgs, GenericParamContext gpContext) { - try { - var caReader = new CustomAttributeReader(module, ref reader, gpContext); - var namedArgs = caReader.ReadNamedArguments(numNamedArgs); - reader.CurrentOffset = caReader.reader.CurrentOffset; - return namedArgs; - } - catch (CABlobParserException) { - return null; - } - catch (IOException) { - return null; - } - } - - CustomAttributeReader(ModuleDefMD readerModule, uint offset, GenericParamContext gpContext) { - module = readerModule; - caBlobOffset = offset; - reader = readerModule.BlobStream.CreateReader(offset); - genericArguments = null; - recursionCounter = new RecursionCounter(); - verifyReadAllBytes = false; - this.gpContext = gpContext; - } - - CustomAttributeReader(ModuleDef module, ref DataReader reader, GenericParamContext gpContext) { - this.module = module; - caBlobOffset = 0; - this.reader = reader; - genericArguments = null; - recursionCounter = new RecursionCounter(); - verifyReadAllBytes = false; - this.gpContext = gpContext; - } - - byte[] GetRawBlob() => reader.ToArray(); - - CustomAttribute Read(ICustomAttributeType ctor) { - var methodSig = ctor?.MethodSig; - 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) { - genericArguments = new GenericArguments(); - genericArguments.PushTypeArgs(gis.GenericArguments); - } - - 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(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(); - var namedArgs = ReadNamedArguments(numNamedArgs); - - // verifyReadAllBytes will be set when we guess the underlying type of an enum. - // To make sure we guessed right, verify that we read all bytes. - if (verifyReadAllBytes && reader.Position != reader.Length) - throw new CABlobParserException("Not all CA blob bytes were read"); - - return new CustomAttribute(ctor, ctorArgs, namedArgs, caBlobOffset); - } - - 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) - break; - namedArgs.Add(ReadNamedArgument()); - } - return namedArgs; - } - - TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); - - TypeSig SubstituteGenericParameter(TypeSig type) { - if (genericArguments is null) - return type; - return genericArguments.Resolve(type); - } - - CAArgument ReadFixedArg(TypeSig argType) { - if (!recursionCounter.Increment()) - throw new CABlobParserException("Too much recursion"); - if (argType is null) - throw new CABlobParserException("null argType"); - CAArgument result; - - if (argType is SZArraySig arrayType) - result = ReadArrayArgument(arrayType); - else - result = ReadElem(argType); - - recursionCounter.Decrement(); - return result; - } - - CAArgument ReadElem(TypeSig argType) { - if (argType is null) - throw new CABlobParserException("null argType"); - var value = ReadValue((SerializationType)argType.ElementType, argType, out var realArgType); - if (realArgType is null) - throw new CABlobParserException("Invalid arg type"); - - // One example when this is true is when prop/field type is object and - // value type is string[] - if (value is CAArgument) - return (CAArgument)value; - - return new CAArgument(realArgType, value); - } - - object ReadValue(SerializationType etype, TypeSig argType, out TypeSig realArgType) { - if (!recursionCounter.Increment()) - throw new CABlobParserException("Too much recursion"); - - object result; - switch (etype) { - case SerializationType.Boolean: - realArgType = module.CorLibTypes.Boolean; - result = reader.ReadByte() != 0; - break; - - case SerializationType.Char: - realArgType = module.CorLibTypes.Char; - result = reader.ReadChar(); - break; - - case SerializationType.I1: - realArgType = module.CorLibTypes.SByte; - result = reader.ReadSByte(); - break; - - case SerializationType.U1: - realArgType = module.CorLibTypes.Byte; - result = reader.ReadByte(); - break; - - case SerializationType.I2: - realArgType = module.CorLibTypes.Int16; - result = reader.ReadInt16(); - break; - - case SerializationType.U2: - realArgType = module.CorLibTypes.UInt16; - result = reader.ReadUInt16(); - break; - - case SerializationType.I4: - realArgType = module.CorLibTypes.Int32; - result = reader.ReadInt32(); - break; - - case SerializationType.U4: - realArgType = module.CorLibTypes.UInt32; - result = reader.ReadUInt32(); - break; - - case SerializationType.I8: - realArgType = module.CorLibTypes.Int64; - result = reader.ReadInt64(); - break; - - case SerializationType.U8: - realArgType = module.CorLibTypes.UInt64; - result = reader.ReadUInt64(); - break; - - case SerializationType.R4: - realArgType = module.CorLibTypes.Single; - result = reader.ReadSingle(); - break; - - case SerializationType.R8: - realArgType = module.CorLibTypes.Double; - result = reader.ReadDouble(); - break; - - case SerializationType.String: - realArgType = module.CorLibTypes.String; - result = ReadUTF8String(); - break; - - // It's ET.ValueType if it's eg. a ctor enum arg type - case (SerializationType)ElementType.ValueType: - if (argType is null) - throw new CABlobParserException("Invalid element type"); - realArgType = argType; - result = ReadEnumValue(GetEnumUnderlyingType(argType)); - break; - - // It's ET.Object if it's a ctor object arg type - case (SerializationType)ElementType.Object: - case SerializationType.TaggedObject: - realArgType = ReadFieldOrPropType(); - var arraySig = realArgType as SZArraySig; - if (arraySig is not null) - result = ReadArrayArgument(arraySig); - 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 - case (SerializationType)ElementType.Class: - var tdr = argType as TypeDefOrRefSig; - if (tdr is not null && tdr.DefinitionAssembly.IsCorLib() && tdr.Namespace == "System") { - if (tdr.TypeName == "Type") { - result = ReadValue(SerializationType.Type, tdr, out realArgType); - break; - } - if (tdr.TypeName == "String") { - result = ReadValue(SerializationType.String, tdr, out realArgType); - break; - } - if (tdr.TypeName == "Object") { - result = ReadValue(SerializationType.TaggedObject, tdr, out realArgType); - break; - } - } - - // Assume it's an enum that couldn't be resolved - realArgType = argType; - result = ReadEnumValue(null); - break; - - case SerializationType.Type: - realArgType = argType; - result = ReadType(true); - break; - - case SerializationType.Enum: - realArgType = ReadType(false); - result = ReadEnumValue(GetEnumUnderlyingType(realArgType)); - break; - - default: - throw new CABlobParserException("Invalid element type"); - } - - recursionCounter.Decrement(); - return result; - } - - object ReadEnumValue(TypeSig underlyingType) { - 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); - } - - // We couldn't resolve the type ref. It should be an enum, but we don't know for sure. - // Most enums use Int32 as the underlying type. Assume that's true also in this case. - // Since we're guessing, verify that we've read all CA blob bytes. If we haven't, then - // we probably guessed wrong. - verifyReadAllBytes = true; - return reader.ReadInt32(); - } - - TypeSig ReadType(bool canReturnNull) { - var name = ReadUTF8String(); - if (canReturnNull && name is null) - return null; - var asmRefFinder = new CAAssemblyRefFinder(module); - var type = TypeNameParser.ParseAsTypeSigReflection(module, UTF8String.ToSystemStringOrEmpty(name), asmRefFinder, gpContext); - if (type is null) - throw new CABlobParserException("Could not parse type"); - return type; - } - - /// - /// Gets the enum's underlying type - /// - /// An enum type - /// 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 is null) - throw new CABlobParserException("null enum type"); - var td = GetTypeDef(type); - if (td is null) - return null; - if (!td.IsEnum) - throw new CABlobParserException("Not an enum"); - return td.GetEnumUnderlyingType().RemoveModifiers(); - } - - /// - /// Converts to a , possibly resolving - /// a - /// - /// The type - /// A or null if we couldn't resolve the - /// or if is a type spec - static TypeDef GetTypeDef(TypeSig type) { - if (type is TypeDefOrRefSig tdr) { - var td = tdr.TypeDef; - if (td is not null) - return td; - - var tr = tdr.TypeRef; - if (tr is not null) - return tr.Resolve(); - } - - return null; - } - - CAArgument ReadArrayArgument(SZArraySig arrayType) { - if (!recursionCounter.Increment()) - throw new CABlobParserException("Too much recursion"); - var arg = new CAArgument(arrayType); - - int arrayCount = reader.ReadInt32(); - if (arrayCount == -1) { // -1 if it's null - } - else if (arrayCount < 0 || arrayCount > reader.BytesLeft) - throw new CABlobParserException("Array is too big"); - else { - var array = new List(arrayCount); - arg.Value = array; - for (int i = 0; i < arrayCount; i++) - array.Add(ReadFixedArg(FixTypeSig(arrayType.Next))); - } - - recursionCounter.Decrement(); - return arg; - } - - CANamedArgument ReadNamedArgument() { - 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); - - return new CANamedArgument(isField, fieldPropType, name, argument); - } - - TypeSig ReadFieldOrPropType() { - if (!recursionCounter.Increment()) - throw new CABlobParserException("Too much recursion"); - 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; - } - - UTF8String ReadUTF8String() { - if (reader.ReadByte() == 0xFF) - return null; - reader.Position--; - if (!reader.TryReadCompressedUInt32(out uint len)) - throw new CABlobParserException("Could not read compressed UInt32"); - if (len == 0) - return UTF8String.Empty; - return new UTF8String(reader.ReadBytes((int)len)); - } - } -} diff --git a/Plugins/dnlib/DotNet/DeclSecurity.cs b/Plugins/dnlib/DotNet/DeclSecurity.cs deleted file mode 100644 index ff9a127..0000000 --- a/Plugins/dnlib/DotNet/DeclSecurity.cs +++ /dev/null @@ -1,227 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the DeclSecurity table - /// - [DebuggerDisplay("{Action} Count={SecurityAttributes.Count}")] - public abstract class DeclSecurity : IHasCustomAttribute, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.DeclSecurity, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 8; - - /// - /// From column DeclSecurity.Action - /// - public SecurityAction Action { - get => action; - set => action = value; - } - /// - protected SecurityAction action; - - /// - /// From column DeclSecurity.PermissionSet - /// - public IList SecurityAttributes { - get { - if (securityAttributes is null) - InitializeSecurityAttributes(); - return securityAttributes; - } - } - /// - protected IList securityAttributes; - /// Initializes - protected virtual void InitializeSecurityAttributes() => - Interlocked.CompareExchange(ref securityAttributes, new List(), null); - - /// - /// 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 => 8; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// true if is not empty - /// - public bool HasSecurityAttributes => SecurityAttributes.Count > 0; - - /// - /// Gets the blob data or null if there's none - /// - /// Blob data or null - public abstract byte[] GetBlob(); - - /// - /// 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); - - internal static string GetNet1xXmlStringInternal(IList secAttrs) { - if (secAttrs is null || secAttrs.Count != 1) - return null; - var sa = secAttrs[0]; - 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 is null || !na.IsProperty || na.Name != "XML") - return null; - if (na.ArgumentType.GetElementType() != ElementType.String) - return null; - var arg = na.Argument; - if (arg.Type.GetElementType() != ElementType.String) - return null; - var utf8 = arg.Value as UTF8String; - if (utf8 is not null) - return utf8; - if (arg.Value is string s) - return s; - return null; - } - } - - /// - /// A DeclSecurity row created by the user and not present in the original .NET file - /// - public class DeclSecurityUser : DeclSecurity { - /// - /// Default constructor - /// - public DeclSecurityUser() { - } - - /// - /// Constructor - /// - /// The security action - /// The security attributes (now owned by this) - public DeclSecurityUser(SecurityAction action, IList securityAttrs) { - this.action = action; - securityAttributes = securityAttrs; - } - - /// - public override byte[] GetBlob() => null; - } - - /// - /// Created from a row in the DeclSecurity table - /// - sealed class DeclSecurityMD : DeclSecurity, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly uint permissionSet; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeSecurityAttributes() { - var gpContext = new GenericParamContext(); - var tmp = DeclSecurityReader.Read(readerModule, permissionSet, gpContext); - Interlocked.CompareExchange(ref securityAttributes, tmp, null); - } - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.DeclSecurity, 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(); - var gpContext = new GenericParamContext(); - readerModule.InitializeCustomDebugInfos(new MDToken(MDToken.Table, origRid), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this DeclSecurity row - /// Row ID - /// If is null - /// If is invalid - public DeclSecurityMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.DeclSecurityTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"DeclSecurity rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadDeclSecurityRow(origRid, out var row); - Debug.Assert(b); - permissionSet = row.PermissionSet; - action = (SecurityAction)row.Action; - } - - /// - public override byte[] GetBlob() => readerModule.BlobStream.Read(permissionSet); - } -} diff --git a/Plugins/dnlib/DotNet/DeclSecurityReader.cs b/Plugins/dnlib/DotNet/DeclSecurityReader.cs deleted file mode 100644 index 6215237..0000000 --- a/Plugins/dnlib/DotNet/DeclSecurityReader.cs +++ /dev/null @@ -1,129 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; - -namespace dnlib.DotNet { - /// - /// Reads DeclSecurity blobs - /// - public struct DeclSecurityReader { - DataReader reader; - readonly ModuleDef module; - readonly GenericParamContext gpContext; - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// #Blob offset of DeclSecurity signature - /// A list of s - public static IList Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateReader(sig), new GenericParamContext()); - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// #Blob offset of DeclSecurity signature - /// Generic parameter context - /// A list of s - public static IList Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateReader(sig), gpContext); - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// DeclSecurity blob - /// A list of s - public static IList Read(ModuleDef module, byte[] blob) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), new GenericParamContext()); - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// DeclSecurity blob - /// Generic parameter context/// - /// A list of s - public static IList Read(ModuleDef module, byte[] blob, GenericParamContext gpContext) => Read(module, ByteArrayDataReaderFactory.CreateReader(blob), gpContext); - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// DeclSecurity stream that will be owned by us - /// A list of s - public static IList Read(ModuleDef module, DataReader signature) => Read(module, signature, new GenericParamContext()); - - /// - /// Reads a DeclSecurity blob - /// - /// Module that will own the returned list - /// DeclSecurity stream that will be owned by us - /// Generic parameter context - /// A list of s - public static IList Read(ModuleDef module, DataReader signature, GenericParamContext gpContext) { - var reader = new DeclSecurityReader(module, signature, gpContext); - return reader.Read(); - } - - DeclSecurityReader(ModuleDef module, DataReader reader, GenericParamContext gpContext) { - this.reader = reader; - this.module = module; - this.gpContext = gpContext; - } - - IList Read() { - try { - if (reader.Position >= reader.Length) - return new List(); - - if (reader.ReadByte() == '.') - return ReadBinaryFormat(); - reader.Position--; - return ReadXmlFormat(); - } - catch { - return new List(); - } - } - - /// - /// Reads the new (.NET Framework 2.0+) DeclSecurity blob format - /// - /// - IList ReadBinaryFormat() { - int numAttrs = (int)reader.ReadCompressedUInt32(); - var list = new List(numAttrs); - - for (int i = 0; i < numAttrs; i++) { - 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 numNamedArgs = (int)reader.ReadCompressedUInt32(); - var namedArgs = CustomAttributeReader.ReadNamedArguments(module, ref reader, numNamedArgs, gpContext); - if (namedArgs is null) - throw new ApplicationException("Could not read named arguments"); - list.Add(new SecurityAttribute(attrRef, namedArgs)); - } - - return list; - } - - /// - /// Reads the old (.NET Framework 1.x) DeclSecurity blob format - /// - /// - IList ReadXmlFormat() { - var xml = reader.ReadUtf16String((int)reader.Length / 2); - var sa = SecurityAttribute.CreateFromXml(module, xml); - return new List { sa }; - } - - UTF8String ReadUTF8String() { - uint len = reader.ReadCompressedUInt32(); - return len == 0 ? UTF8String.Empty : new UTF8String(reader.ReadBytes((int)len)); - } - } -} diff --git a/Plugins/dnlib/DotNet/ElementType.cs b/Plugins/dnlib/DotNet/ElementType.cs deleted file mode 100644 index df727e8..0000000 --- a/Plugins/dnlib/DotNet/ElementType.cs +++ /dev/null @@ -1,209 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// See CorHdr.h/CorElementType - /// - public enum ElementType : byte { - /// - End = 0x00, - /// System.Void - Void = 0x01, - /// System.Boolean - Boolean = 0x02, - /// System.Char - Char = 0x03, - /// System.SByte - I1 = 0x04, - /// System.Byte - U1 = 0x05, - /// System.Int16 - I2 = 0x06, - /// System.UInt16 - U2 = 0x07, - /// System.Int32 - I4 = 0x08, - /// System.UInt32 - U4 = 0x09, - /// System.Int64 - I8 = 0x0A, - /// System.UInt64 - U8 = 0x0B, - /// System.Single - R4 = 0x0C, - /// System.Double - R8 = 0x0D, - /// System.String - String = 0x0E, - /// Pointer type (*) - Ptr = 0x0F, - /// ByRef type (&) - ByRef = 0x10, - /// Value type - ValueType = 0x11, - /// Reference type - Class = 0x12, - /// Type generic parameter - Var = 0x13, - /// Multidimensional array ([*], [,], [,,], ...) - Array = 0x14, - /// Generic instance type - GenericInst = 0x15, - /// Typed byref - TypedByRef = 0x16, - /// Value array (don't use) - ValueArray = 0x17, - /// System.IntPtr - I = 0x18, - /// System.UIntPtr - U = 0x19, - /// native real (don't use) - R = 0x1A, - /// Function pointer - FnPtr = 0x1B, - /// System.Object - Object = 0x1C, - /// Single-dimension, zero lower bound array ([]) - SZArray = 0x1D, - /// Method generic parameter - MVar = 0x1E, - /// Required C modifier - CModReqd = 0x1F, - /// Optional C modifier - CModOpt = 0x20, - /// Used internally by the CLR (don't use) - Internal = 0x21, - /// Module (don't use) - Module = 0x3F, - /// Sentinel (method sigs only) - Sentinel = 0x41, - /// Pinned type (locals only) - Pinned = 0x45, - } - - public static partial class Extensions { - /// - /// Returns true if it's an integer or a floating point type - /// - /// Element type - /// - public static bool IsPrimitive(this ElementType etype) { - switch (etype) { - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.I: - case ElementType.U: - case ElementType.R: - return true; - - default: - return false; - } - } - - /// - /// 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 = -1) { - switch (etype) { - case ElementType.Boolean: - case ElementType.I1: - case ElementType.U1: - return 1; - - case ElementType.Char: - case ElementType.I2: - case ElementType.U2: - return 2; - - case ElementType.I4: - case ElementType.U4: - case ElementType.R4: - return 4; - - case ElementType.I8: - case ElementType.U8: - case ElementType.R8: - return 8; - - case ElementType.Ptr: - case ElementType.FnPtr: - case ElementType.I: - case ElementType.U: - return ptrSize; - - default: - return -1; - } - } - - /// - /// Checks whether it's a value type - /// - /// this - /// true if it's a value type, false if it's not a value type or - /// if we couldn't determine whether it's a value type. Eg., it could be a generic - /// instance type. - public static bool IsValueType(this ElementType etype) { - switch (etype) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.ValueType: - case ElementType.TypedByRef: - case ElementType.ValueArray: - case ElementType.I: - case ElementType.U: - case ElementType.R: - return true; - - case ElementType.GenericInst: - // We don't have enough info to determine whether this is a value type - return false; - - case ElementType.End: - case ElementType.String: - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Class: - case ElementType.Var: - case ElementType.Array: - case ElementType.FnPtr: - case ElementType.Object: - case ElementType.SZArray: - case ElementType.MVar: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Internal: - case ElementType.Module: - case ElementType.Sentinel: - case ElementType.Pinned: - default: - return false; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/Code.cs b/Plugins/dnlib/DotNet/Emit/Code.cs deleted file mode 100644 index 9491639..0000000 --- a/Plugins/dnlib/DotNet/Emit/Code.cs +++ /dev/null @@ -1,296 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -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. - /// - public enum Code : ushort { -#pragma warning disable 1591 // disable XML doc warning - UNKNOWN1 = 0x0100, - UNKNOWN2 = 0x0101, - Add = 0x0058, - Add_Ovf = 0x00D6, - Add_Ovf_Un = 0x00D7, - And = 0x005F, - Arglist = 0xFE00, - Beq = 0x003B, - Beq_S = 0x002E, - Bge = 0x003C, - Bge_S = 0x002F, - Bge_Un = 0x0041, - Bge_Un_S = 0x0034, - Bgt = 0x003D, - Bgt_S = 0x0030, - Bgt_Un = 0x0042, - Bgt_Un_S = 0x0035, - Ble = 0x003E, - Ble_S = 0x0031, - Ble_Un = 0x0043, - Ble_Un_S = 0x0036, - Blt = 0x003F, - Blt_S = 0x0032, - Blt_Un = 0x0044, - Blt_Un_S = 0x0037, - Bne_Un = 0x0040, - Bne_Un_S = 0x0033, - Box = 0x008C, - Br = 0x0038, - Br_S = 0x002B, - Break = 0x0001, - Brfalse = 0x0039, - Brfalse_S = 0x002C, - Brtrue = 0x003A, - Brtrue_S = 0x002D, - Call = 0x0028, - Calli = 0x0029, - Callvirt = 0x006F, - Castclass = 0x0074, - Ceq = 0xFE01, - Cgt = 0xFE02, - Cgt_Un = 0xFE03, - Ckfinite = 0x00C3, - Clt = 0xFE04, - Clt_Un = 0xFE05, - Constrained = 0xFE16, - Conv_I = 0x00D3, - Conv_I1 = 0x0067, - Conv_I2 = 0x0068, - Conv_I4 = 0x0069, - Conv_I8 = 0x006A, - Conv_Ovf_I = 0x00D4, - Conv_Ovf_I_Un = 0x008A, - Conv_Ovf_I1 = 0x00B3, - Conv_Ovf_I1_Un = 0x0082, - Conv_Ovf_I2 = 0x00B5, - Conv_Ovf_I2_Un = 0x0083, - Conv_Ovf_I4 = 0x00B7, - Conv_Ovf_I4_Un = 0x0084, - Conv_Ovf_I8 = 0x00B9, - Conv_Ovf_I8_Un = 0x0085, - Conv_Ovf_U = 0x00D5, - Conv_Ovf_U_Un = 0x008B, - Conv_Ovf_U1 = 0x00B4, - Conv_Ovf_U1_Un = 0x0086, - Conv_Ovf_U2 = 0x00B6, - Conv_Ovf_U2_Un = 0x0087, - Conv_Ovf_U4 = 0x00B8, - Conv_Ovf_U4_Un = 0x0088, - Conv_Ovf_U8 = 0x00BA, - Conv_Ovf_U8_Un = 0x0089, - Conv_R_Un = 0x0076, - Conv_R4 = 0x006B, - Conv_R8 = 0x006C, - Conv_U = 0x00E0, - Conv_U1 = 0x00D2, - Conv_U2 = 0x00D1, - Conv_U4 = 0x006D, - Conv_U8 = 0x006E, - Cpblk = 0xFE17, - Cpobj = 0x0070, - Div = 0x005B, - Div_Un = 0x005C, - Dup = 0x0025, - Endfilter = 0xFE11, - Endfinally = 0x00DC, - Initblk = 0xFE18, - Initobj = 0xFE15, - Isinst = 0x0075, - Jmp = 0x0027, - Ldarg = 0xFE09, - Ldarg_0 = 0x0002, - Ldarg_1 = 0x0003, - Ldarg_2 = 0x0004, - Ldarg_3 = 0x0005, - Ldarg_S = 0x000E, - Ldarga = 0xFE0A, - Ldarga_S = 0x000F, - Ldc_I4 = 0x0020, - Ldc_I4_0 = 0x0016, - Ldc_I4_1 = 0x0017, - Ldc_I4_2 = 0x0018, - Ldc_I4_3 = 0x0019, - Ldc_I4_4 = 0x001A, - Ldc_I4_5 = 0x001B, - Ldc_I4_6 = 0x001C, - Ldc_I4_7 = 0x001D, - Ldc_I4_8 = 0x001E, - Ldc_I4_M1 = 0x0015, - Ldc_I4_S = 0x001F, - Ldc_I8 = 0x0021, - Ldc_R4 = 0x0022, - Ldc_R8 = 0x0023, - Ldelem = 0x00A3, - Ldelem_I = 0x0097, - Ldelem_I1 = 0x0090, - Ldelem_I2 = 0x0092, - Ldelem_I4 = 0x0094, - Ldelem_I8 = 0x0096, - Ldelem_R4 = 0x0098, - Ldelem_R8 = 0x0099, - Ldelem_Ref = 0x009A, - Ldelem_U1 = 0x0091, - Ldelem_U2 = 0x0093, - Ldelem_U4 = 0x0095, - Ldelema = 0x008F, - Ldfld = 0x007B, - Ldflda = 0x007C, - Ldftn = 0xFE06, - Ldind_I = 0x004D, - Ldind_I1 = 0x0046, - Ldind_I2 = 0x0048, - Ldind_I4 = 0x004A, - Ldind_I8 = 0x004C, - Ldind_R4 = 0x004E, - Ldind_R8 = 0x004F, - Ldind_Ref = 0x0050, - Ldind_U1 = 0x0047, - Ldind_U2 = 0x0049, - Ldind_U4 = 0x004B, - Ldlen = 0x008E, - Ldloc = 0xFE0C, - Ldloc_0 = 0x0006, - Ldloc_1 = 0x0007, - Ldloc_2 = 0x0008, - Ldloc_3 = 0x0009, - Ldloc_S = 0x0011, - Ldloca = 0xFE0D, - Ldloca_S = 0x0012, - Ldnull = 0x0014, - Ldobj = 0x0071, - Ldsfld = 0x007E, - Ldsflda = 0x007F, - Ldstr = 0x0072, - Ldtoken = 0x00D0, - Ldvirtftn = 0xFE07, - Leave = 0x00DD, - Leave_S = 0x00DE, - Localloc = 0xFE0F, - Mkrefany = 0x00C6, - Mul = 0x005A, - Mul_Ovf = 0x00D8, - Mul_Ovf_Un = 0x00D9, - Neg = 0x0065, - Newarr = 0x008D, - Newobj = 0x0073, - No = 0xFE19, - Nop = 0x0000, - Not = 0x0066, - Or = 0x0060, - Pop = 0x0026, - Prefix1 = 0x00FE, - Prefix2 = 0x00FD, - Prefix3 = 0x00FC, - Prefix4 = 0x00FB, - Prefix5 = 0x00FA, - Prefix6 = 0x00F9, - Prefix7 = 0x00F8, - Prefixref = 0x00FF, - Readonly = 0xFE1E, - Refanytype = 0xFE1D, - Refanyval = 0x00C2, - Rem = 0x005D, - Rem_Un = 0x005E, - Ret = 0x002A, - Rethrow = 0xFE1A, - Shl = 0x0062, - Shr = 0x0063, - Shr_Un = 0x0064, - Sizeof = 0xFE1C, - Starg = 0xFE0B, - Starg_S = 0x0010, - Stelem = 0x00A4, - Stelem_I = 0x009B, - Stelem_I1 = 0x009C, - Stelem_I2 = 0x009D, - Stelem_I4 = 0x009E, - Stelem_I8 = 0x009F, - Stelem_R4 = 0x00A0, - Stelem_R8 = 0x00A1, - Stelem_Ref = 0x00A2, - Stfld = 0x007D, - Stind_I = 0x00DF, - Stind_I1 = 0x0052, - Stind_I2 = 0x0053, - Stind_I4 = 0x0054, - Stind_I8 = 0x0055, - Stind_R4 = 0x0056, - Stind_R8 = 0x0057, - Stind_Ref = 0x0051, - Stloc = 0xFE0E, - Stloc_0 = 0x000A, - Stloc_1 = 0x000B, - Stloc_2 = 0x000C, - Stloc_3 = 0x000D, - Stloc_S = 0x0013, - Stobj = 0x0081, - Stsfld = 0x0080, - Sub = 0x0059, - Sub_Ovf = 0x00DA, - Sub_Ovf_Un = 0x00DB, - Switch = 0x0045, - Tailcall = 0xFE14, - Throw = 0x007A, - Unaligned = 0xFE12, - Unbox = 0x0079, - Unbox_Any = 0x00A5, - Volatile = 0xFE13, - Xor = 0x0061, -#pragma warning restore - } - - 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) { - 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) - return OpCodes.UNKNOWN2; - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/DynamicMethodBodyReader.cs b/Plugins/dnlib/DotNet/Emit/DynamicMethodBodyReader.cs deleted file mode 100644 index a90ff32..0000000 --- a/Plugins/dnlib/DotNet/Emit/DynamicMethodBodyReader.cs +++ /dev/null @@ -1,569 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using SR = System.Reflection; -using System.Reflection.Emit; -using System.IO; -using dnlib.DotNet.MD; -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 - /// - public class DynamicMethodBodyReader : MethodBodyReaderBase, ISignatureReaderHelper { - static readonly ReflectionFieldInfo rtdmOwnerFieldInfo = new ReflectionFieldInfo("m_owner"); - 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"); - static readonly ReflectionFieldInfo rslvLocalsFieldInfo = new ReflectionFieldInfo("m_localSignature"); - static readonly ReflectionFieldInfo rslvMaxStackFieldInfo = new ReflectionFieldInfo("m_stackSize"); - static readonly ReflectionFieldInfo rslvExceptionsFieldInfo = new ReflectionFieldInfo("m_exceptions"); - static readonly ReflectionFieldInfo rslvExceptionHeaderFieldInfo = new ReflectionFieldInfo("m_exceptionHeader"); - static readonly ReflectionFieldInfo scopeTokensFieldInfo = new ReflectionFieldInfo("m_tokens"); - static readonly ReflectionFieldInfo gfiFieldHandleFieldInfo = new ReflectionFieldInfo("m_field", "m_fieldHandle"); - static readonly ReflectionFieldInfo gfiContextFieldInfo = new ReflectionFieldInfo("m_context"); - static readonly ReflectionFieldInfo gmiMethodHandleFieldInfo = new ReflectionFieldInfo("m_method", "m_methodHandle"); - static readonly ReflectionFieldInfo gmiContextFieldInfo = new ReflectionFieldInfo("m_context"); - static readonly ReflectionFieldInfo ehCatchAddrFieldInfo = new ReflectionFieldInfo("m_catchAddr"); - static readonly ReflectionFieldInfo ehCatchClassFieldInfo = new ReflectionFieldInfo("m_catchClass"); - static readonly ReflectionFieldInfo ehCatchEndAddrFieldInfo = new ReflectionFieldInfo("m_catchEndAddr"); - static readonly ReflectionFieldInfo ehCurrentCatchFieldInfo = new ReflectionFieldInfo("m_currentCatch"); - static readonly ReflectionFieldInfo ehTypeFieldInfo = new ReflectionFieldInfo("m_type"); - static readonly ReflectionFieldInfo ehStartAddrFieldInfo = new ReflectionFieldInfo("m_startAddr"); - static readonly ReflectionFieldInfo ehEndAddrFieldInfo = new ReflectionFieldInfo("m_endAddr"); - 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; - readonly GenericParamContext gpContext; - readonly MethodDef method; - readonly int codeSize; - readonly int maxStack; - readonly bool initLocals; - readonly List tokens; - readonly IList ehInfos; - readonly byte[] ehHeader; - readonly string methodName; - readonly DynamicMethodBodyReaderOptions options; - - class ReflectionFieldInfo { - SR.FieldInfo fieldInfo; - readonly string fieldName1; - readonly string fieldName2; - - public ReflectionFieldInfo(string fieldName) => fieldName1 = fieldName; - - public ReflectionFieldInfo(string fieldName1, string fieldName2) { - this.fieldName1 = fieldName1; - this.fieldName2 = fieldName2; - } - - public object Read(object instance) { - if (fieldInfo is null) - InitializeField(instance.GetType()); - if (fieldInfo is null) - throw new Exception($"Couldn't find field '{fieldName1}' or '{fieldName2}'"); - - return fieldInfo.GetValue(instance); - } - - public bool Exists(object instance) { - InitializeField(instance.GetType()); - return fieldInfo is not null; - } - - void InitializeField(Type type) { - if (fieldInfo is not null) - return; - - 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); - } - } - - /// - /// 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. - public DynamicMethodBodyReader(ModuleDef module, object obj) - : this(module, obj, new GenericParamContext()) { - } - - /// - /// 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. - /// Generic parameter context - public DynamicMethodBodyReader(ModuleDef module, object obj, GenericParamContext gpContext) - : this(module, obj, new Importer(module, ImporterOptions.TryToUseDefs, gpContext), 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 - 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) - : base(module.Context) { - this.module = module; - this.importer = importer; - this.options = options; - gpContext = importer.gpContext; - methodName = null; - - if (obj is null) - throw new ArgumentNullException(nameof(obj)); - - if (obj is Delegate del) { - obj = del.Method; - 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 is null) - throw new Exception("RTDynamicMethod.m_owner is null or invalid"); - } - - if (obj is DynamicMethod dynMethod) { - methodName = dynMethod.Name; - obj = dmResolverFieldInfo.Read(obj) ?? dmDynamicILInfoFieldInfo.Read(obj);; - if (obj is null) - throw new Exception("No resolver found"); - } - - 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) - throw new Exception("No code"); - codeSize = code.Length; - var delMethod = rslvMethodFieldInfo.Read(obj) as DynamicMethod; - if (delMethod is null) - throw new Exception("No method"); - initLocals = delMethod.InitLocals; - maxStack = isILInfo ? (int)dynILInfoMaxStackFieldInfo.Read(obj) : (int)rslvMaxStackFieldInfo.Read(obj); - - var scope = rslvDynamicScopeFieldInfo.Read(obj); - if (scope is null) - throw new Exception("No scope"); - var tokensList = scopeTokensFieldInfo.Read(scope) as System.Collections.IList; - if (tokensList is null) - throw new Exception("No tokens"); - tokens = new List(tokensList.Count); - for (int i = 0; i < tokensList.Count; i++) - tokens.Add(tokensList[i]); - - 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); - method = CreateMethodDef(delMethod); - parameters = method.Parameters; - } - - class ExceptionInfo { - public int[] CatchAddr; - public Type[] CatchClass; - public int[] CatchEndAddr; - public int CurrentCatch; - public int[] Type; - public int StartAddr; - public int EndAddr; - public int EndFinally; - } - - static List CreateExceptionInfos(IList ehInfos) { - if (ehInfos is null) - return new List(); - - var infos = new List(ehInfos.Count); - - 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), - CatchEndAddr = (int[])ehCatchEndAddrFieldInfo.Read(ehInfo), - CurrentCatch = (int)ehCurrentCatchFieldInfo.Read(ehInfo), - Type = (int[])ehTypeFieldInfo.Read(ehInfo), - StartAddr = (int)ehStartAddrFieldInfo.Read(ehInfo), - EndAddr = (int)ehEndAddrFieldInfo.Read(ehInfo), - EndFinally = (int)ehEndFinallyFieldInfo.Read(ehInfo), - }; - infos.Add(eh); - } - - return infos; - } - - void UpdateLocals(byte[] localsSig) { - if (localsSig is null || localsSig.Length == 0) - return; - - var sig = SignatureReader.ReadSig(this, module.CorLibTypes, localsSig, gpContext) as LocalSig; - if (sig is null) - return; - - 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) { - bool isStatic = true; - var method = new MethodDefUser(); - - var retType = GetReturnType(delMethod); - var pms = GetParameters(delMethod); - if (isStatic) - method.Signature = MethodSig.CreateStatic(retType, pms.ToArray()); - else - method.Signature = MethodSig.CreateInstance(retType, pms.ToArray()); - - method.Parameters.UpdateParameterTypes(); - method.ImplAttributes = MethodImplAttributes.IL; - method.Attributes = MethodAttributes.PrivateScope; - if (isStatic) - method.Attributes |= MethodAttributes.Static; - - return module.UpdateRowId(method); - } - - TypeSig GetReturnType(SR.MethodBase mb) { - if (mb is SR.MethodInfo mi) - return importer.ImportAsTypeSig(mi.ReturnType); - return module.CorLibTypes.Void; - } - - List GetParameters(SR.MethodBase delMethod) { - var pms = new List(); - foreach (var param in delMethod.GetParameters()) - pms.Add(importer.ImportAsTypeSig(param.ParameterType)); - return pms; - } - - /// - /// Reads the code - /// - /// - public bool Read() { - ReadInstructionsNumBytes((uint)codeSize); - CreateExceptionHandlers(); - - return true; - } - - void CreateExceptionHandlers() { - if (ehHeader is not null) { - if (ehHeader.Length < 4) - return; - var reader = new BinaryReader(new MemoryStream(ehHeader)); - 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.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.ReadUInt16(); - int offs = reader.ReadUInt16(); - eh.TryStart = GetInstructionThrow((uint)offs); - eh.TryEnd = GetInstruction((uint)(reader.ReadByte() + offs)); - offs = reader.ReadUInt16(); - eh.HandlerStart = GetInstructionThrow((uint)offs); - eh.HandlerEnd = GetInstruction((uint)(reader.ReadByte() + offs)); - - if (eh.IsCatch) - eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - else if (eh.IsFilter) - eh.FilterStart = GetInstruction(reader.ReadUInt32()); - else - reader.ReadUInt32(); - - exceptionHandlers.Add(eh); - } - } - else { - 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.ReadUInt32(); - var offs = reader.ReadUInt32(); - eh.TryStart = GetInstructionThrow((uint)offs); - eh.TryEnd = GetInstruction((uint)(reader.ReadUInt32() + offs)); - offs = reader.ReadUInt32(); - eh.HandlerStart = GetInstructionThrow((uint)offs); - eh.HandlerEnd = GetInstruction((uint)(reader.ReadUInt32() + offs)); - - if (eh.IsCatch) - eh.CatchType = ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - else if (eh.IsFilter) - eh.FilterStart = GetInstruction(reader.ReadUInt32()); - else - reader.ReadUInt32(); - - exceptionHandlers.Add(eh); - } - } - } - else if (ehInfos is not null) { - foreach (var ehInfo in CreateExceptionInfos(ehInfos)) { - var tryStart = GetInstructionThrow((uint)ehInfo.StartAddr); - var tryEnd = GetInstruction((uint)ehInfo.EndAddr); - var endFinally = ehInfo.EndFinally < 0 ? null : GetInstruction((uint)ehInfo.EndFinally); - for (int i = 0; i < ehInfo.CurrentCatch; i++) { - var eh = new ExceptionHandler(); - eh.HandlerType = (ExceptionHandlerType)ehInfo.Type[i]; - eh.TryStart = tryStart; - 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]); - eh.CatchType = importer.Import(ehInfo.CatchClass[i]); - exceptionHandlers.Add(eh); - } - } - } - } - - /// - /// Returns the created method. Must be called after . - /// - /// A new instance - public MethodDef GetMethod() { - var cilBody = new CilBody(initLocals, instructions, exceptionHandlers, locals); - cilBody.MaxStack = (ushort)Math.Min(maxStack, ushort.MaxValue); - instructions = null; - exceptionHandlers = null; - locals = null; - method.Body = cilBody; - method.Name = methodName; - return method; - } - - /// - protected override IField ReadInlineField(Instruction instr) => ReadToken(reader.ReadUInt32()) as IField; - - /// - protected override IMethod ReadInlineMethod(Instruction instr) => ReadToken(reader.ReadUInt32()) as IMethod; - - /// - protected override MethodSig ReadInlineSig(Instruction instr) => ReadToken(reader.ReadUInt32()) as MethodSig; - - /// - protected override string ReadInlineString(Instruction instr) => ReadToken(reader.ReadUInt32()) as string ?? string.Empty; - - /// - protected override ITokenOperand ReadInlineTok(Instruction instr) => ReadToken(reader.ReadUInt32()) as ITokenOperand; - - /// - protected override ITypeDefOrRef ReadInlineType(Instruction instr) => ReadToken(reader.ReadUInt32()) as ITypeDefOrRef; - - object ReadToken(uint token) { - uint rid = token & 0x00FFFFFF; - switch (token >> 24) { - case 0x02: - return ImportType(rid); - - case 0x04: - return ImportField(rid); - - case 0x06: - case 0x0A: - return ImportMethod(rid); - - case 0x11: - return ImportSignature(rid); - - case 0x70: - return Resolve(rid) as string; - - default: - return null; - } - } - - IMethod ImportMethod(uint rid) { - var obj = Resolve(rid); - if (obj is null) - return null; - - if (obj is RuntimeMethodHandle) { - 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") { - var context = (RuntimeTypeHandle)gmiContextFieldInfo.Read(obj); - var method = SR.MethodBase.GetMethodFromHandle((RuntimeMethodHandle)gmiMethodHandleFieldInfo.Read(obj), context); - return importer.Import(method); - } - - if (obj.GetType().ToString() == "System.Reflection.Emit.VarArgMethod") { - var method = GetVarArgMethod(obj); - if (!(method is DynamicMethod)) - return importer.Import(method); - obj = method; - } - - if (obj is DynamicMethod dm) - throw new Exception("DynamicMethod calls another DynamicMethod"); - - return null; - } - - SR.MethodInfo GetVarArgMethod(object obj) { - if (vamDynamicMethodFieldInfo.Exists(obj)) { - // .NET Framework 4.0+ - var method = vamMethodFieldInfo.Read(obj) as SR.MethodInfo; - var dynMethod = vamDynamicMethodFieldInfo.Read(obj) as DynamicMethod; - return dynMethod ?? method; - } - else { - // .NET Framework 2.0 - // This is either a DynamicMethod or a MethodInfo - return vamMethodFieldInfo.Read(obj) as SR.MethodInfo; - } - } - - IField ImportField(uint rid) { - var obj = Resolve(rid); - if (obj is null) - return null; - - if (obj is RuntimeFieldHandle) { - 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") { - var context = (RuntimeTypeHandle)gfiContextFieldInfo.Read(obj); - var field = SR.FieldInfo.GetFieldFromHandle((RuntimeFieldHandle)gfiFieldHandleFieldInfo.Read(obj), context); - return importer.Import(field); - } - - return null; - } - - ITypeDefOrRef ImportType(uint rid) { - var obj = Resolve(rid); - if (obj is RuntimeTypeHandle) - return importer.Import(Type.GetTypeFromHandle((RuntimeTypeHandle)obj)); - - return null; - } - - CallingConventionSig ImportSignature(uint rid) { - var sig = Resolve(rid) as byte[]; - if (sig is null) - return null; - - return SignatureReader.ReadSig(this, module.CorLibTypes, sig, gpContext); - } - - object Resolve(uint index) { - if (index >= (uint)tokens.Count) - return null; - 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; - switch (MDToken.ToTable(token)) { - case Table.TypeDef: - case Table.TypeRef: - case Table.TypeSpec: - return module.ResolveToken(token) as ITypeDefOrRef; - } - return null; - } - - TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) => importer.ImportAsTypeSig(MethodTableToTypeConverter.Convert(address)); - } -} diff --git a/Plugins/dnlib/DotNet/Emit/ExceptionHandler.cs b/Plugins/dnlib/DotNet/Emit/ExceptionHandler.cs deleted file mode 100644 index e98f6bc..0000000 --- a/Plugins/dnlib/DotNet/Emit/ExceptionHandler.cs +++ /dev/null @@ -1,78 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// A CIL method exception handler - /// - public sealed class ExceptionHandler { - /// - /// First instruction of try block - /// - public Instruction TryStart; - - /// - /// One instruction past the end of try block or null if it ends at the end - /// of the method. - /// - public Instruction TryEnd; - - /// - /// Start of filter handler or null if none. The end of filter handler is - /// always . - /// - public Instruction FilterStart; - - /// - /// First instruction of try handler block - /// - public Instruction HandlerStart; - - /// - /// One instruction past the end of try handler block or null if it ends at the end - /// of the method. - /// - public Instruction HandlerEnd; - - /// - /// The catch type if is - /// - public ITypeDefOrRef CatchType; - - /// - /// Type of exception handler clause - /// - 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 - /// - public ExceptionHandler() { - } - - /// - /// Constructor - /// - /// Exception clause type - public ExceptionHandler(ExceptionHandlerType handlerType) => HandlerType = handlerType; - } -} diff --git a/Plugins/dnlib/DotNet/Emit/ExceptionHandlerType.cs b/Plugins/dnlib/DotNet/Emit/ExceptionHandlerType.cs deleted file mode 100644 index d5b80ef..0000000 --- a/Plugins/dnlib/DotNet/Emit/ExceptionHandlerType.cs +++ /dev/null @@ -1,22 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.Emit { - /// - /// Type of exception handler. See CorHdr.h/CorExceptionFlag - /// - [Flags] - public enum ExceptionHandlerType { - /// - Catch = 0x0000, - /// - Filter = 0x0001, - /// - Finally = 0x0002, - /// - Fault = 0x0004, - /// - Duplicated = 0x0008, - } -} diff --git a/Plugins/dnlib/DotNet/Emit/Extensions.cs b/Plugins/dnlib/DotNet/Emit/Extensions.cs deleted file mode 100644 index fcbb4f3..0000000 --- a/Plugins/dnlib/DotNet/Emit/Extensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// Extension methods - /// - public static partial class Extensions { - } -} diff --git a/Plugins/dnlib/DotNet/Emit/FlowControl.cs b/Plugins/dnlib/DotNet/Emit/FlowControl.cs deleted file mode 100644 index d29b86f..0000000 --- a/Plugins/dnlib/DotNet/Emit/FlowControl.cs +++ /dev/null @@ -1,27 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// CIL opcode flow control - /// - public enum FlowControl { - /// - Branch, - /// - Break, - /// - Call, - /// - Cond_Branch, - /// - Meta, - /// - Next, - /// - Phi, - /// - Return, - /// - Throw, - } -} diff --git a/Plugins/dnlib/DotNet/Emit/Instruction.cs b/Plugins/dnlib/DotNet/Emit/Instruction.cs deleted file mode 100644 index 3013665..0000000 --- a/Plugins/dnlib/DotNet/Emit/Instruction.cs +++ /dev/null @@ -1,827 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet.Emit { - /// - /// A CIL instruction (opcode + operand) - /// - public sealed class Instruction { - /// - /// The opcode - /// - public OpCode OpCode; - - /// - /// The opcode operand - /// - public object Operand; - - /// - /// Offset of the instruction in the method body - /// - public uint Offset; - - /// - /// PDB sequence point or null if none - /// - public SequencePoint SequencePoint; - - /// - /// Default constructor - /// - public Instruction() { - } - - /// - /// Constructor - /// - /// Opcode - public Instruction(OpCode opCode) => OpCode = opCode; - - /// - /// Constructor - /// - /// Opcode - /// The operand - public Instruction(OpCode opCode, object operand) { - OpCode = opCode; - Operand = operand; - } - - /// - /// Creates a new instruction with no operand - /// - /// The opcode - /// A new instance - public static Instruction Create(OpCode opCode) { - if (opCode.OperandType != OperandType.InlineNone) - throw new ArgumentException("Must be a no-operand opcode", nameof(opCode)); - return new Instruction(opCode); - } - - /// - /// Creates a new instruction with a operand - /// - /// The opcode - /// The value - /// 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with a operand - /// - /// The opcode - /// The 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with an operand - /// - /// The opcode - /// The 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with a operand - /// - /// The opcode - /// The 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with a operand - /// - /// The opcode - /// The 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with a operand - /// - /// The opcode - /// The 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", nameof(opCode)); - return new Instruction(opCode, value); - } - - /// - /// Creates a new instruction with a string operand - /// - /// The opcode - /// The string - /// 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", nameof(opCode)); - return new Instruction(opCode, s); - } - - /// - /// Creates a new instruction with an instruction target operand - /// - /// The opcode - /// Target instruction - /// 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", nameof(opCode)); - return new Instruction(opCode, target); - } - - /// - /// Creates a new instruction with an instruction target list operand - /// - /// The opcode - /// The targets - /// 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", nameof(opCode)); - return new Instruction(opCode, targets); - } - - /// - /// Creates a new instruction with a type operand - /// - /// The opcode - /// The type - /// 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", nameof(opCode)); - return new Instruction(opCode, type); - } - - /// - /// Creates a new instruction with a type operand - /// - /// The opcode - /// The type - /// A new instance - public static Instruction Create(OpCode opCode, CorLibTypeSig type) => Create(opCode, type.TypeDefOrRef); - - /// - /// Creates a new instruction with a method/field operand - /// - /// The opcode - /// The method/field - /// 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", nameof(opCode)); - return new Instruction(opCode, mr); - } - - /// - /// Creates a new instruction with a field operand - /// - /// The opcode - /// The field - /// 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", nameof(opCode)); - return new Instruction(opCode, field); - } - - /// - /// Creates a new instruction with a method operand - /// - /// The opcode - /// The method - /// 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", nameof(opCode)); - return new Instruction(opCode, method); - } - - /// - /// Creates a new instruction with a token operand - /// - /// The opcode - /// The token - /// 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", nameof(opCode)); - return new Instruction(opCode, token); - } - - /// - /// Creates a new instruction with a method signature operand - /// - /// The opcode - /// The method signature - /// 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", nameof(opCode)); - return new Instruction(opCode, methodSig); - } - - /// - /// Creates a new instruction with a method parameter operand - /// - /// The opcode - /// The method parameter - /// 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", nameof(opCode)); - return new Instruction(opCode, parameter); - } - - /// - /// Creates a new instruction with a method local operand - /// - /// The opcode - /// The method local - /// 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", nameof(opCode)); - return new Instruction(opCode, local); - } - - /// - /// Creates a ldci4 instruction - /// - /// Operand value - /// A new instance - public static Instruction CreateLdcI4(int value) { - switch (value) { - case -1:return OpCodes.Ldc_I4_M1.ToInstruction(); - case 0: return OpCodes.Ldc_I4_0.ToInstruction(); - case 1: return OpCodes.Ldc_I4_1.ToInstruction(); - case 2: return OpCodes.Ldc_I4_2.ToInstruction(); - case 3: return OpCodes.Ldc_I4_3.ToInstruction(); - case 4: return OpCodes.Ldc_I4_4.ToInstruction(); - case 5: return OpCodes.Ldc_I4_5.ToInstruction(); - case 6: return OpCodes.Ldc_I4_6.ToInstruction(); - case 7: return OpCodes.Ldc_I4_7.ToInstruction(); - case 8: return OpCodes.Ldc_I4_8.ToInstruction(); - } - if (sbyte.MinValue <= value && value <= sbyte.MaxValue) - return new Instruction(OpCodes.Ldc_I4_S, (sbyte)value); - return new Instruction(OpCodes.Ldc_I4, value); - } - - /// - /// Gets the size in bytes of the instruction - /// - /// - public int GetSize() { - var opCode = OpCode; - switch (opCode.OperandType) { - case OperandType.InlineBrTarget: - case OperandType.InlineField: - case OperandType.InlineI: - case OperandType.InlineMethod: - case OperandType.InlineSig: - case OperandType.InlineString: - case OperandType.InlineTok: - case OperandType.InlineType: - case OperandType.ShortInlineR: - return opCode.Size + 4; - - case OperandType.InlineI8: - case OperandType.InlineR: - return opCode.Size + 8; - - case OperandType.InlineNone: - case OperandType.InlinePhi: - default: - return opCode.Size; - - case OperandType.InlineSwitch: - var targets = Operand as IList; - return opCode.Size + 4 + (targets is null ? 0 : targets.Count * 4); - - case OperandType.InlineVar: - return opCode.Size + 2; - - case OperandType.ShortInlineBrTarget: - case OperandType.ShortInlineI: - case OperandType.ShortInlineVar: - return opCode.Size + 1; - } - } - - 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); - - /// - /// Updates with the new stack size - /// - /// Current stack size - /// true if the method has a return value, - /// false otherwise - public void UpdateStack(ref int stack, bool methodHasReturnValue) { - CalculateStackUsage(methodHasReturnValue, out int pushes, out int pops); - if (pops == -1) - stack = 0; - else - stack += pushes - pops; - } - - /// - /// Calculates stack usage - /// - /// 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); - - /// - /// Calculates stack usage - /// - /// true if method has a return value - /// Updated with number of stack pushes - /// Updated with number of stack pops or -1 if the stack should - /// be cleared. - public void CalculateStackUsage(bool methodHasReturnValue, out int pushes, out int pops) { - var opCode = OpCode; - if (opCode.FlowControl == FlowControl.Call) - CalculateStackUsageCall(opCode.Code, out pushes, out pops); - else - CalculateStackUsageNonCall(opCode, methodHasReturnValue, out pushes, out 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 (code == Code.Jmp) - return; - - MethodSig sig; - var op = Operand; - if (op is IMethod method) - sig = method.MethodSig; - else - sig = op as MethodSig; // calli instruction - if (sig is null) - return; - bool implicitThis = sig.ImplicitThis; - if (!IsSystemVoid(sig.RetType) || (code == Code.Newobj && sig.HasThis)) - pushes++; - - pops += sig.Params.Count; - var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (paramsAfterSentinel is not null) - pops += paramsAfterSentinel.Count; - if (implicitThis && code != Code.Newobj) - pops++; - if (code == Code.Calli) - pops++; - } - - void CalculateStackUsageNonCall(OpCode opCode, bool hasReturnValue, out int pushes, out int pops) { - switch (opCode.StackBehaviourPush) { - case StackBehaviour.Push0: - pushes = 0; - break; - - case StackBehaviour.Push1: - case StackBehaviour.Pushi: - case StackBehaviour.Pushi8: - case StackBehaviour.Pushr4: - case StackBehaviour.Pushr8: - case StackBehaviour.Pushref: - pushes = 1; - break; - - case StackBehaviour.Push1_push1: - pushes = 2; - break; - - case StackBehaviour.Varpush: // only call, calli, callvirt which are handled elsewhere - default: - pushes = 0; - break; - } - - switch (opCode.StackBehaviourPop) { - case StackBehaviour.Pop0: - pops = 0; - break; - - case StackBehaviour.Pop1: - case StackBehaviour.Popi: - case StackBehaviour.Popref: - pops = 1; - break; - - case StackBehaviour.Pop1_pop1: - case StackBehaviour.Popi_pop1: - case StackBehaviour.Popi_popi: - case StackBehaviour.Popi_popi8: - case StackBehaviour.Popi_popr4: - case StackBehaviour.Popi_popr8: - case StackBehaviour.Popref_pop1: - case StackBehaviour.Popref_popi: - pops = 2; - break; - - case StackBehaviour.Popi_popi_popi: - case StackBehaviour.Popref_popi_popi: - case StackBehaviour.Popref_popi_popi8: - case StackBehaviour.Popref_popi_popr4: - case StackBehaviour.Popref_popi_popr8: - case StackBehaviour.Popref_popi_popref: - case StackBehaviour.Popref_popi_pop1: - pops = 3; - break; - - case StackBehaviour.PopAll: - pops = -1; - break; - - case StackBehaviour.Varpop: // call, calli, callvirt, newobj (all handled elsewhere), and ret - if (hasReturnValue) - pops = 1; - else - pops = 0; - break; - - default: - pops = 0; - break; - } - } - - /// - /// Checks whether it's one of the leave instructions - /// - public bool IsLeave() => OpCode == OpCodes.Leave || OpCode == OpCodes.Leave_S; - - /// - /// Checks whether it's one of the br instructions - /// - public bool IsBr() => OpCode == OpCodes.Br || OpCode == OpCodes.Br_S; - - /// - /// Checks whether it's one of the brfalse instructions - /// - public bool IsBrfalse() => OpCode == OpCodes.Brfalse || OpCode == OpCodes.Brfalse_S; - - /// - /// Checks whether it's one of the brtrue instructions - /// - public bool IsBrtrue() => OpCode == OpCodes.Brtrue || OpCode == OpCodes.Brtrue_S; - - /// - /// Checks whether it's one of the conditional branch instructions (bcc, brtrue, brfalse) - /// - public bool IsConditionalBranch() { - switch (OpCode.Code) { - case Code.Bge: - case Code.Bge_S: - case Code.Bge_Un: - case Code.Bge_Un_S: - case Code.Blt: - case Code.Blt_S: - case Code.Blt_Un: - case Code.Blt_Un_S: - case Code.Bgt: - case Code.Bgt_S: - case Code.Bgt_Un: - case Code.Bgt_Un_S: - case Code.Ble: - case Code.Ble_S: - case Code.Ble_Un: - case Code.Ble_Un_S: - case Code.Brfalse: - case Code.Brfalse_S: - case Code.Brtrue: - case Code.Brtrue_S: - case Code.Beq: - case Code.Beq_S: - case Code.Bne_Un: - case Code.Bne_Un_S: - return true; - - default: - return false; - } - } - - /// - /// Checks whether this is one of the ldc.i4 instructions - /// - public bool IsLdcI4() { - switch (OpCode.Code) { - case Code.Ldc_I4_M1: - case Code.Ldc_I4_0: - case Code.Ldc_I4_1: - case Code.Ldc_I4_2: - case Code.Ldc_I4_3: - case Code.Ldc_I4_4: - case Code.Ldc_I4_5: - case Code.Ldc_I4_6: - case Code.Ldc_I4_7: - case Code.Ldc_I4_8: - case Code.Ldc_I4_S: - case Code.Ldc_I4: - return true; - default: - return false; - } - } - - /// - /// Returns a ldc.i4 instruction's operand - /// - /// The integer value - /// isn't one of the - /// ldc.i4 opcodes - 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 - /// whether it's one of the ldarga instructions. - /// - public bool IsLdarg() { - switch (OpCode.Code) { - case Code.Ldarg: - case Code.Ldarg_S: - case Code.Ldarg_0: - case Code.Ldarg_1: - case Code.Ldarg_2: - case Code.Ldarg_3: - return true; - default: - return false; - } - } - - /// - /// Checks whether it's one of the ldloc instructions, but does not check - /// whether it's one of the ldloca instructions. - /// - public bool IsLdloc() { - switch (OpCode.Code) { - case Code.Ldloc: - case Code.Ldloc_0: - case Code.Ldloc_1: - case Code.Ldloc_2: - case Code.Ldloc_3: - case Code.Ldloc_S: - return true; - default: - return false; - } - } - - /// - /// Checks whether it's one of the starg instructions - /// - public bool IsStarg() { - switch (OpCode.Code) { - case Code.Starg: - case Code.Starg_S: - return true; - default: - return false; - } - } - - /// - /// Checks whether it's one of the stloc instructions - /// - public bool IsStloc() { - switch (OpCode.Code) { - case Code.Stloc: - case Code.Stloc_0: - case Code.Stloc_1: - case Code.Stloc_2: - case Code.Stloc_3: - case Code.Stloc_S: - return true; - default: - return false; - } - } - - /// - /// Returns the local if it's a ldloc, stloc or ldloca instruction - /// - /// The locals - /// 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; - var code = OpCode.Code; - switch (code) { - case Code.Ldloc: - 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: - case Code.Ldloc_1: - case Code.Ldloc_2: - case Code.Ldloc_3: - index = code - Code.Ldloc_0; - break; - - case Code.Stloc_0: - case Code.Stloc_1: - case Code.Stloc_2: - case Code.Stloc_3: - index = code - Code.Stloc_0; - break; - - default: - return null; - } - - if ((uint)index < (uint)locals.Count) - return locals[index]; - return null; - } - - /// - /// Gets the index of the instruction's parameter operand or -1 if the parameter - /// is missing or if it's not an instruction with a parameter operand. - /// - public int GetParameterIndex() { - switch (OpCode.Code) { - case Code.Ldarg_0: return 0; - case Code.Ldarg_1: return 1; - case Code.Ldarg_2: return 2; - case Code.Ldarg_3: return 3; - - case Code.Starg: - case Code.Starg_S: - case Code.Ldarga: - case Code.Ldarga_S: - case Code.Ldarg: - case Code.Ldarg_S: - var parameter = Operand as Parameter; - if (parameter is not null) - return parameter.Index; - break; - } - - return -1; - } - - /// - /// Returns a method parameter - /// - /// All parameters - /// A parameter or null if it doesn't exist - public Parameter GetParameter(IList parameters) { - int i = GetParameterIndex(); - if ((uint)i < (uint)parameters.Count) - return parameters[i]; - return null; - } - - /// - /// Returns an argument type - /// - /// Method signature - /// 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 is null) - return null; - int index = GetParameterIndex(); - 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) - return methodSig.Params[index]; - return null; - } - - /// - /// Clone this instance. The and fields - /// are shared by this instance and the created instance. - /// - public Instruction Clone() => - new Instruction { - Offset = Offset, - OpCode = OpCode, - Operand = Operand, - SequencePoint = SequencePoint, - }; - - /// - public override string ToString() => InstructionPrinter.ToString(this); - } - - static partial class Extensions { - /// - /// Gets the opcode or if is null - /// - /// this - /// - 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) => self?.Operand; - - /// - /// Gets the offset or 0 if is null - /// - /// this - /// - 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) => self?.SequencePoint; - } -} diff --git a/Plugins/dnlib/DotNet/Emit/InstructionPrinter.cs b/Plugins/dnlib/DotNet/Emit/InstructionPrinter.cs deleted file mode 100644 index 5e1830d..0000000 --- a/Plugins/dnlib/DotNet/Emit/InstructionPrinter.cs +++ /dev/null @@ -1,168 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Text; - -namespace dnlib.DotNet.Emit { - /// - /// Converts instructions to strings - /// - public static class InstructionPrinter { - /// - /// Converts an instruction to a string - /// - /// The instruction - /// The result - public static string ToString(Instruction instr) { - if (instr is null) - return string.Empty; - - var sb = new StringBuilder(); - - sb.Append($"IL_{instr.Offset:X4}: "); - sb.Append(instr.OpCode.Name); - AddOperandString(sb, instr, " "); - - return sb.ToString(); - } - - /// - /// Gets the instruction's operand as a string - /// - /// The instruction - /// The operand as a string - public static string GetOperandString(Instruction instr) { - var sb = new StringBuilder(); - AddOperandString(sb, instr, string.Empty); - return sb.ToString(); - } - - /// - /// Add an instruction's operand to - /// - /// Place result here - /// The instruction - public static void AddOperandString(StringBuilder sb, Instruction instr) => AddOperandString(sb, instr, string.Empty); - - /// - /// Add an instruction's operand to - /// - /// Place result here - /// The instruction - /// A string that will be added before the operand, if there's - /// an operand. - public static void AddOperandString(StringBuilder sb, Instruction instr, string extra) { - var op = instr.Operand; - switch (instr.OpCode.OperandType) { - case OperandType.InlineBrTarget: - case OperandType.ShortInlineBrTarget: - sb.Append(extra); - AddInstructionTarget(sb, op as Instruction); - break; - - case OperandType.InlineField: - case OperandType.InlineMethod: - case OperandType.InlineTok: - case OperandType.InlineType: - sb.Append(extra); - if (op is IFullName) - sb.Append((op as IFullName).FullName); - else if (op is not null) - sb.Append(op.ToString()); - else - sb.Append("null"); - break; - - case OperandType.InlineI: - case OperandType.InlineI8: - case OperandType.InlineR: - case OperandType.ShortInlineI: - case OperandType.ShortInlineR: - sb.Append($"{extra}{op}"); - break; - - case OperandType.InlineSig: - sb.Append(extra); - FullNameFactory.MethodFullNameSB(null, (UTF8String)null, op as MethodSig, null, null, null, sb); - break; - - case OperandType.InlineString: - sb.Append(extra); - EscapeString(sb, op as string, true); - break; - - case OperandType.InlineSwitch: - var targets = op as IList; - if (targets is null) - sb.Append("null"); - else { - sb.Append('('); - for (int i = 0; i < targets.Count; i++) { - if (i != 0) - sb.Append(','); - AddInstructionTarget(sb, targets[i]); - } - sb.Append(')'); - } - break; - - case OperandType.InlineVar: - case OperandType.ShortInlineVar: - sb.Append(extra); - if (op is null) - sb.Append("null"); - else - sb.Append(op.ToString()); - break; - - case OperandType.InlineNone: - case OperandType.InlinePhi: - default: - break; - } - } - - static void AddInstructionTarget(StringBuilder sb, Instruction targetInstr) { - 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 is null) { - sb.Append("null"); - return; - } - - if (addQuotes) - sb.Append('"'); - - foreach (var c in s) { - if ((int)c < 0x20) { - switch (c) { - case '\a': sb.Append(@"\a"); break; - case '\b': sb.Append(@"\b"); break; - case '\f': sb.Append(@"\f"); break; - case '\n': sb.Append(@"\n"); break; - case '\r': sb.Append(@"\r"); break; - case '\t': sb.Append(@"\t"); break; - case '\v': sb.Append(@"\v"); break; - default: - sb.Append($@"\u{(int)c:X4}"); - break; - } - } - else if (c == '\\' || c == '"') { - sb.Append('\\'); - sb.Append(c); - } - else - sb.Append(c); - } - - if (addQuotes) - sb.Append('"'); - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/InvalidMethodException.cs b/Plugins/dnlib/DotNet/Emit/InvalidMethodException.cs deleted file mode 100644 index 8538ac1..0000000 --- a/Plugins/dnlib/DotNet/Emit/InvalidMethodException.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.Serialization; - -namespace dnlib.DotNet.Emit { - /// - /// Thrown when invalid data is detected while parsing a .NET method - /// - [Serializable] - public class InvalidMethodException : Exception { - /// - /// Default constructor - /// - public InvalidMethodException() { - } - - /// - /// Constructor - /// - /// Error message - public InvalidMethodException(string msg) - : base(msg) { - } - - /// - /// Constructor - /// - /// Error message - /// The inner exception or null if none - public InvalidMethodException(string msg, Exception innerException) - : base(msg, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected InvalidMethodException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/LocalList.cs b/Plugins/dnlib/DotNet/Emit/LocalList.cs deleted file mode 100644 index 700f557..0000000 --- a/Plugins/dnlib/DotNet/Emit/LocalList.cs +++ /dev/null @@ -1,195 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.Utils; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet.Emit { - /// - /// A collection of s - /// - [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(LocalList_CollectionDebugView))] - public sealed class LocalList : IListListener, IList { - readonly LazyList locals; - - /// - /// Gets the number of locals - /// - public int Count => locals.Count; - - /// - /// Gets the list of locals - /// - public IList Locals => locals; - - /// - /// Gets the N'th local - /// - /// The local index - public Local this[int index] { - get => locals[index]; - set => locals[index] = value; - } - - /// - /// Default constructor - /// - public LocalList() => locals = new LazyList(this); - - /// - /// Constructor - /// - /// All locals that will be owned by this instance - public LocalList(IList locals) { - this.locals = new LazyList(this); - for (int i = 0; i < locals.Count; i++) - this.locals.Add(locals[i]); - } - - /// - /// Adds a new local and then returns it - /// - /// The local that should be added to the list - /// The input is always returned - public Local Add(Local local) { - locals.Add(local); - return local; - } - - /// - void IListListener.OnLazyAdd(int index, ref Local value) { - } - - /// - void IListListener.OnAdd(int index, Local value) => value.Index = index; - - /// - void IListListener.OnRemove(int index, Local value) => value.Index = -1; - - /// - void IListListener.OnResize(int index) { - for (int i = index; i < locals.Count_NoLock; i++) - locals.Get_NoLock(i).Index = i; - } - - /// - void IListListener.OnClear() { - foreach (var local in locals.GetEnumerable_NoLock()) - local.Index = -1; - } - - /// - public int IndexOf(Local item) => locals.IndexOf(item); - - /// - public void Insert(int index, Local item) => locals.Insert(index, item); - - /// - public void RemoveAt(int index) => locals.RemoveAt(index); - - void ICollection.Add(Local item) => locals.Add(item); - - /// - public void Clear() => locals.Clear(); - - /// - public bool Contains(Local item) => locals.Contains(item); - - /// - public void CopyTo(Local[] array, int arrayIndex) => locals.CopyTo(array, arrayIndex); - - /// - public bool IsReadOnly => false; - - /// - public bool Remove(Local item) => locals.Remove(item); - - /// - public LazyList.Enumerator GetEnumerator() => locals.GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => locals.GetEnumerator(); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => ((IEnumerable)this).GetEnumerator(); - } - - /// - /// A method local - /// - public sealed class Local : IVariable { - TypeSig typeSig; - int index; - string name; - PdbLocalAttributes attributes; - - /// - /// Gets/sets the type of the local - /// - public TypeSig Type { - get => typeSig; - set => typeSig = value; - } - - /// - /// Local index - /// - public int Index { - 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 => 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 => attributes; - set => attributes = value; - } - - 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; - - /// - /// 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; - if (string.IsNullOrEmpty(n)) - return $"V_{Index}"; - return n; - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/MethodBody.cs b/Plugins/dnlib/DotNet/Emit/MethodBody.cs deleted file mode 100644 index d21b39f..0000000 --- a/Plugins/dnlib/DotNet/Emit/MethodBody.cs +++ /dev/null @@ -1,216 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Pdb; -using dnlib.PE; - -namespace dnlib.DotNet.Emit { - /// - /// Method body base class - /// - public abstract class MethodBody { - } - - /// - /// A native method body - /// - public sealed class NativeMethodBody : MethodBody { - RVA rva; - - /// - /// Gets/sets the RVA of the native method body - /// - public RVA RVA { - get => rva; - set => rva = value; - } - - /// - /// Default constructor - /// - public NativeMethodBody() { - } - - /// - /// Constructor - /// - /// RVA of method body - public NativeMethodBody(RVA rva) => this.rva = rva; - } - - /// - /// CIL (managed code) body - /// - public sealed class CilBody : MethodBody { - bool keepOldMaxStack; - bool initLocals; - byte headerSize; - ushort maxStack; - uint localVarSigTok; - readonly IList instructions; - readonly IList exceptionHandlers; - readonly LocalList localList; - - /// - /// Size of a small header - /// - public const byte SMALL_HEADER_SIZE = 1; - - /// - /// Gets/sets a flag indicating whether the original max stack value should be used. - /// - public bool KeepOldMaxStack { - 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 => initLocals; - set => initLocals = value; - } - - /// - /// Gets/sets the size in bytes of the method body header. The instructions immediately follow - /// the header. - /// - public byte HeaderSize { - get => headerSize; - set => headerSize = value; - } - - /// - /// true if it was a small body header ( is 1) - /// - public bool IsSmallHeader => headerSize == SMALL_HEADER_SIZE; - - /// - /// true if it was a big body header - /// - public bool IsBigHeader => headerSize != SMALL_HEADER_SIZE; - - /// - /// Gets/sets max stack value from the fat method header. - /// - public ushort MaxStack { - get => maxStack; - set => maxStack = value; - } - - /// - /// Gets/sets the locals metadata token - /// - public uint LocalVarSigTok { - get => localVarSigTok; - set => localVarSigTok = value; - } - - /// - /// true if is not empty - /// - public bool HasInstructions => instructions.Count > 0; - - /// - /// Gets the instructions - /// - public IList Instructions => instructions; - - /// - /// true if is not empty - /// - public bool HasExceptionHandlers => exceptionHandlers.Count > 0; - - /// - /// Gets the exception handlers - /// - public IList ExceptionHandlers => exceptionHandlers; - - /// - /// true if is not empty - /// - public bool HasVariables => localList.Count > 0; - - /// - /// Gets the locals - /// - 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 => pdbMethod; - set => pdbMethod = value; - } - PdbMethod pdbMethod; - - /// - /// true if is not 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. - /// This property returns 0 if the size is unknown. - /// - internal uint MetadataBodySize { get; set; } - - /// - /// Default constructor - /// - public CilBody() { - initLocals = true; - instructions = new List(); - exceptionHandlers = new List(); - localList = new LocalList(); - } - - /// - /// Constructor - /// - /// Init locals flag - /// All instructions. This instance will own the list. - /// All exception handlers. This instance will own the list. - /// All locals. This instance will own the locals in the list. - public CilBody(bool initLocals, IList instructions, IList exceptionHandlers, IList locals) { - this.initLocals = initLocals; - this.instructions = instructions; - this.exceptionHandlers = exceptionHandlers; - localList = new LocalList(locals); - } - - /// - /// Shorter instructions are converted to the longer form, eg. Ldc_I4_1 is - /// converted to Ldc_I4 with a 1 as the operand. - /// - /// All method parameters, including the hidden 'this' parameter - /// if it's an instance method. Use . - 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(); - - /// - /// Short branch instructions are converted to the long form, eg. Beq_S is - /// converted to Beq. - /// - public void SimplifyBranches() => instructions.SimplifyBranches(); - - /// - /// Optimizes branches by using the smallest possible branch - /// - public void OptimizeBranches() => instructions.OptimizeBranches(); - - /// - /// Updates each instruction's offset - /// - /// Total size in bytes of all instructions - public uint UpdateInstructionOffsets() => instructions.UpdateInstructionOffsets(); - } -} diff --git a/Plugins/dnlib/DotNet/Emit/MethodBodyReader.cs b/Plugins/dnlib/DotNet/Emit/MethodBodyReader.cs deleted file mode 100644 index 232c73e..0000000 --- a/Plugins/dnlib/DotNet/Emit/MethodBodyReader.cs +++ /dev/null @@ -1,542 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.IO; -using dnlib.IO; - -namespace dnlib.DotNet.Emit { - /// - /// Reads strings from #US heap - /// - public interface IStringResolver { - /// - /// Reads a string from the #US heap - /// - /// String token - /// A string - string ReadUserString(uint token); - } - - /// - /// Resolves instruction operands - /// - public interface IInstructionOperandResolver : ITokenResolver, IStringResolver { - } - - public static partial class Extensions { - /// - /// Resolves a token - /// - /// An object - /// The metadata token - /// A or null if is invalid - public static IMDTokenProvider ResolveToken(this IInstructionOperandResolver self, uint token) => - self.ResolveToken(token, new GenericParamContext()); - } - - /// - /// Reads a .NET method body (header, locals, instructions, exception handlers) - /// - public sealed class MethodBodyReader : MethodBodyReaderBase { - readonly IInstructionOperandResolver opResolver; - bool hasReadHeader; - byte headerSize; - ushort flags; - ushort maxStack; - uint codeSize; - uint localVarSigTok; - uint startOfHeader; - uint totalBodySize; - DataReader? exceptionsReader; - readonly GenericParamContext 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 - /// Use parameters from this method - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader reader, MethodDef method) => - CreateCilBody(opResolver, reader, null, method.Parameters, new GenericParamContext()); - - /// - /// 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 - /// Use parameters from this method - /// Generic parameter context - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader 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 - /// 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 - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader reader, IList parameters) => - CreateCilBody(opResolver, reader, null, parameters, new GenericParamContext()); - - /// - /// 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 - 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. - /// - /// The operand resolver - /// All code - /// Exceptions or null if all exception handlers are in - /// - /// Method parameters - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, byte[] code, byte[] exceptions, IList parameters) => - 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 - /// a valid CIL method body. - /// - /// The operand resolver - /// All code - /// Exceptions or null if all exception handlers are in - /// - /// 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 is null ? (DataReader?)null : ByteArrayDataReaderFactory.CreateReader(exceptions), 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 - /// Exception handler reader or null if exceptions aren't - /// present or if contains the exception handlers - /// Method parameters - public static CilBody CreateCilBody(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters) => - CreateCilBody(opResolver, codeReader, ehReader, parameters, new GenericParamContext()); - - /// - /// 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 - 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(); - } - - /// - /// 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 - 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 - /// 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 - 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, context); - mbReader.SetHeader(flags, maxStack, codeSize, localVarSigTok); - if (!mbReader.Read()) - return new CilBody(); - return mbReader.CreateCilBody(); - } - - /// - /// Constructor - /// - /// The operand resolver - /// A reader positioned at the start of a .NET method body - /// Use parameters from this method - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader reader, MethodDef method) - : this(opResolver, reader, null, method.Parameters, new GenericParamContext()) { - } - - /// - /// Constructor - /// - /// The operand resolver - /// A reader positioned at the start of a .NET method body - /// Use parameters from this method - /// Generic parameter context - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader reader, MethodDef method, GenericParamContext gpContext) - : this(opResolver, reader, null, method.Parameters, gpContext) { - } - - /// - /// Constructor - /// - /// The operand resolver - /// A reader positioned at the start of a .NET method body - /// Method parameters - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader reader, IList parameters) - : this(opResolver, reader, null, parameters, new GenericParamContext()) { - } - - /// - /// Constructor - /// - /// The operand resolver - /// A reader positioned at the start of a .NET method body - /// Method parameters - /// Generic parameter context - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader reader, IList parameters, GenericParamContext gpContext) - : this(opResolver, reader, null, parameters, gpContext) { - } - - /// - /// 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 - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters) - : this(opResolver, codeReader, ehReader, parameters, new GenericParamContext()) { - } - - /// - /// 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 - public MethodBodyReader(IInstructionOperandResolver opResolver, DataReader codeReader, DataReader? ehReader, IList parameters, GenericParamContext gpContext) - : 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; - startOfHeader = uint.MaxValue; - } - - /// - /// Initializes the method header - /// - /// Header flags, eg. 2 if it's a tiny method - /// Max stack - /// Code size - /// Local variable signature token - void SetHeader(ushort flags, ushort maxStack, uint codeSize, uint localVarSigTok) { - hasReadHeader = true; - this.flags = flags; - this.maxStack = maxStack; - this.codeSize = codeSize; - this.localVarSigTok = localVarSigTok; - } - - /// - /// Reads the method body header, locals, all instructions, and the exception handlers (if any) - /// - /// true if it worked, and false if something failed - public bool Read() { - try { - if (!ReadHeader()) - return false; - SetLocals(ReadLocals()); - ReadInstructions(); - ReadExceptionHandlers(out totalBodySize); - return true; - } - catch (InvalidMethodException) { - return false; - } - catch (IOException) { - return false; - } - } - - /// - /// Reads the method header - /// - bool ReadHeader() { - if (hasReadHeader) - return true; - hasReadHeader = true; - - startOfHeader = reader.Position; - byte b = reader.ReadByte(); - switch (b & 7) { - case 2: - case 6: - // Tiny header. [7:2] = code size, max stack is 8, no locals or exception handlers - flags = 2; - maxStack = 8; - codeSize = (uint)(b >> 2); - localVarSigTok = 0; - headerSize = 1; - break; - - case 3: - // Fat header. Can have locals and exception handlers - flags = (ushort)((reader.ReadByte() << 8) | b); - headerSize = (byte)(flags >> 12); - maxStack = reader.ReadUInt16(); - codeSize = reader.ReadUInt32(); - localVarSigTok = reader.ReadUInt32(); - - // The CLR allows the code to start inside the method header. But if it does, - // the CLR doesn't read any exceptions. - reader.Position = reader.Position - 12 + headerSize * 4U; - if (headerSize < 3) - flags &= 0xFFF7; - headerSize *= 4; - break; - - default: - return false; - } - - if ((ulong)reader.Position + codeSize > reader.Length) - return false; - - return true; - } - - /// - /// Reads the locals - /// - /// All locals or null if there are none - IList ReadLocals() { - var standAloneSig = opResolver.ResolveToken(localVarSigTok, gpContext) as StandAloneSig; - if (standAloneSig is null) - return null; - var localSig = standAloneSig.LocalSig; - if (localSig is null) - return null; - return localSig.Locals; - } - - /// - /// Reads all instructions - /// - void ReadInstructions() => ReadInstructionsNumBytes(codeSize); - - /// - protected override IField ReadInlineField(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IField; - - /// - protected override IMethod ReadInlineMethod(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as IMethod; - - /// - protected override MethodSig ReadInlineSig(Instruction instr) { - var standAloneSig = opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as StandAloneSig; - if (standAloneSig is null) - return null; - var sig = standAloneSig.MethodSig; - if (sig is not null) - sig.OriginalToken = standAloneSig.MDToken.Raw; - return sig; - } - - /// - protected override string ReadInlineString(Instruction instr) => opResolver.ReadUserString(reader.ReadUInt32()) ?? string.Empty; - - /// - protected override ITokenOperand ReadInlineTok(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITokenOperand; - - /// - protected override ITypeDefOrRef ReadInlineType(Instruction instr) => opResolver.ResolveToken(reader.ReadUInt32(), gpContext) as ITypeDefOrRef; - - /// - /// Reads all exception handlers - /// - void ReadExceptionHandlers(out uint totalBodySize) { - if ((flags & 8) == 0) { - totalBodySize = startOfHeader == uint.MaxValue ? 0 : reader.Position - startOfHeader; - return; - } - bool canSaveTotalBodySize; - DataReader ehReader; - if (exceptionsReader is not 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) { - 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; - } - - void ReadFatExceptionHandlers(ref DataReader ehReader) { - ehReader.Position--; - 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(); - eh.TryStart = GetInstruction(offs); - eh.TryEnd = GetInstruction(offs + ehReader.ReadUInt32()); - offs = ehReader.ReadUInt32(); - eh.HandlerStart = GetInstruction(offs); - eh.HandlerEnd = GetInstruction(offs + ehReader.ReadUInt32()); - if (eh.IsCatch) - eh.CatchType = opResolver.ResolveToken(ehReader.ReadUInt32(), gpContext) as ITypeDefOrRef; - else if (eh.IsFilter) - eh.FilterStart = GetInstruction(ehReader.ReadUInt32()); - else - ehReader.ReadUInt32(); - Add(eh); - } - } - - void ReadSmallExceptionHandlers(ref DataReader ehReader) { - int num = (int)((uint)ehReader.ReadByte() / 12); - ehReader.Position += 2; - for (int i = 0; i < num; i++) { - var eh = new ExceptionHandler((ExceptionHandlerType)ehReader.ReadUInt16()); - uint offs = ehReader.ReadUInt16(); - eh.TryStart = GetInstruction(offs); - eh.TryEnd = GetInstruction(offs + ehReader.ReadByte()); - offs = ehReader.ReadUInt16(); - eh.HandlerStart = GetInstruction(offs); - eh.HandlerEnd = GetInstruction(offs + ehReader.ReadByte()); - if (eh.IsCatch) - eh.CatchType = opResolver.ResolveToken(ehReader.ReadUInt32(), gpContext) as ITypeDefOrRef; - else if (eh.IsFilter) - eh.FilterStart = GetInstruction(ehReader.ReadUInt32()); - else - ehReader.ReadUInt32(); - Add(eh); - } - } - - /// - /// Creates a CIL body. Must be called after , and can only be - /// called once. - /// - /// A new instance - public CilBody CreateCilBody() { - // Set init locals if it's a tiny method or if the init locals bit is set (fat header) - bool initLocals = flags == 2 || (flags & 0x10) != 0; - var cilBody = new CilBody(initLocals, instructions, exceptionHandlers, locals); - cilBody.HeaderSize = headerSize; - cilBody.MaxStack = maxStack; - cilBody.LocalVarSigTok = localVarSigTok; - cilBody.MetadataBodySize = totalBodySize; - instructions = null; - exceptionHandlers = null; - locals = null; - return cilBody; - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/MethodBodyReaderBase.cs b/Plugins/dnlib/DotNet/Emit/MethodBodyReaderBase.cs deleted file mode 100644 index fd81be9..0000000 --- a/Plugins/dnlib/DotNet/Emit/MethodBodyReaderBase.cs +++ /dev/null @@ -1,587 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; - -namespace dnlib.DotNet.Emit { - /// - /// Method body reader base class - /// - public abstract class MethodBodyReaderBase { - /// The method reader - protected DataReader reader; - /// All parameters - protected IList parameters; - /// All locals - protected IList locals = new List(); - /// All instructions - protected IList instructions; - /// All exception handlers - protected IList exceptionHandlers = new List(); - uint currentOffset; - /// First byte after the end of the code - protected uint codeEndOffs; - /// Start offset of method - protected uint codeStartOffs; - readonly ModuleContext context; - - /// - /// Gets all parameters - /// - public IList Parameters => parameters; - - /// - /// Gets all locals - /// - public IList Locals => locals; - - /// - /// Gets all instructions - /// - public IList Instructions => instructions; - - /// - /// Gets all exception handlers - /// - public IList ExceptionHandlers => exceptionHandlers; - - /// - /// Constructor - /// - protected MethodBodyReaderBase() { - } - - /// - /// Constructor - /// - /// The module context - protected MethodBodyReaderBase(ModuleContext context) { - this.context = context; - } - - /// - /// Constructor - /// - /// The reader - protected MethodBodyReaderBase(DataReader reader) - : this(reader, null) { - } - - /// - /// Constructor - /// - /// The reader - /// Method parameters or null if they're not known yet - 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; - } - - /// - /// Sets new locals - /// - /// A list of types of all locals or null if none - protected void SetLocals(IList newLocals) { - var locals = this.locals; - locals.Clear(); - if (newLocals is null) - return; - int count = newLocals.Count; - for (int i = 0; i < count; i++) - locals.Add(new Local(newLocals[i])); - } - - /// - /// Sets new locals - /// - /// A list of types of all locals or null if none - protected void SetLocals(IList newLocals) { - var locals = this.locals; - locals.Clear(); - if (newLocals is null) - return; - int count = newLocals.Count; - for (int i = 0; i < count; i++) - locals.Add(new Local(newLocals[i].Type)); - } - - /// - /// Reads all instructions - /// - /// Number of instructions to read - protected void ReadInstructions(int numInstrs) { - codeStartOffs = reader.Position; - codeEndOffs = reader.Length; // We don't know the end pos so use the last one - 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(); - } - - /// - /// Reads all instructions - /// - /// Size of code - protected void ReadInstructionsNumBytes(uint codeSize) { - codeStartOffs = reader.Position; - codeEndOffs = reader.Position + codeSize; - if (codeEndOffs < codeStartOffs || codeEndOffs > reader.Length) - throw new InvalidMethodException("Invalid code size"); - - 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; - FixBranches(); - } - - /// - /// Fixes all branch instructions so their operands are set to an - /// instead of an offset. - /// - void FixBranches() { - 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: - instr.Operand = GetInstruction((uint)instr.Operand); - break; - - case OperandType.InlineSwitch: - var uintTargets = (IList)instr.Operand; - var targets = new Instruction[uintTargets.Count]; - for (int j = 0; j < uintTargets.Count; j++) - targets[j] = GetInstruction(uintTargets[j]); - instr.Operand = targets; - break; - } - } - } - - /// - /// Finds an instruction - /// - /// Offset of instruction - /// 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; - var instr = instructions[i]; - if (instr.Offset == offset) - return instr; - if (offset < instr.Offset) - hi = i - 1; - else - lo = i + 1; - } - return null; - } - - /// - /// Finds an instruction and throws if it's not present - /// - /// Offset of instruction - /// The instruction - /// There's no instruction at - /// - protected Instruction GetInstructionThrow(uint offset) { - var instr = GetInstruction(offset); - if (instr is not null) - return instr; - throw new InvalidOperationException($"There's no instruction @ {offset:X4}"); - } - - /// - /// Reads the next instruction - /// - Instruction ReadOneInstruction() { - var instr = new Instruction(); - instr.Offset = currentOffset; - instr.OpCode = ReadOpCode(); - instr.Operand = ReadOperand(instr); - - if (instr.OpCode.Code == Code.Switch) { - var targets = (IList)instr.Operand; - currentOffset += (uint)(instr.OpCode.Size + 4 + 4 * targets.Count); - } - else - currentOffset += (uint)instr.GetSize(); - if (currentOffset < instr.Offset) - reader.Position = codeEndOffs; - return instr; - } - - /// - /// Reads the next OpCode from the current position - /// - OpCode ReadOpCode() { - var op = reader.ReadByte(); - if (op == 0xFE) - return OpCodes.TwoByteOpCodes[reader.ReadByte()]; - if (op >= 0xF0 && op <= 0xFB && context is not null && reader.BytesLeft >= 1) { - if (context.GetExperimentalOpCode(op, reader.ReadByte()) is OpCode opCode) - return opCode; - else - reader.Position--; - } - return OpCodes.OneByteOpCodes[op]; - } - - /// - /// Reads the instruction operand (if any) - /// - /// The instruction - 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 - /// - /// The current instruction - /// The operand - protected virtual uint ReadInlineBrTarget(Instruction instr) => instr.Offset + (uint)instr.GetSize() + reader.ReadUInt32(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract IField ReadInlineField(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual int ReadInlineI(Instruction instr) => reader.ReadInt32(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual long ReadInlineI8(Instruction instr) => reader.ReadInt64(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract IMethod ReadInlineMethod(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual object ReadInlineNone(Instruction instr) => null; - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual object ReadInlinePhi(Instruction instr) => null; - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual double ReadInlineR(Instruction instr) => reader.ReadDouble(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract MethodSig ReadInlineSig(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract string ReadInlineString(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual IList ReadInlineSwitch(Instruction instr) { - var num = reader.ReadUInt32(); - long offsetAfterInstr = (long)instr.Offset + (long)instr.OpCode.Size + 4L + (long)num * 4; - if (offsetAfterInstr > uint.MaxValue || codeStartOffs + offsetAfterInstr > codeEndOffs) { - reader.Position = codeEndOffs; - return Array2.Empty(); - } - - var targets = new uint[num]; - uint offset = (uint)offsetAfterInstr; - for (int i = 0; i < targets.Length; i++) - targets[i] = offset + reader.ReadUInt32(); - return targets; - } - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract ITokenOperand ReadInlineTok(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected abstract ITypeDefOrRef ReadInlineType(Instruction instr); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual IVariable ReadInlineVar(Instruction instr) { - if (IsArgOperandInstruction(instr)) - return ReadInlineVarArg(instr); - return ReadInlineVarLocal(instr); - } - - /// - /// Reads a (a parameter) operand - /// - /// The current instruction - /// The operand - 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) => GetLocal(reader.ReadUInt16()); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual uint ReadShortInlineBrTarget(Instruction instr) => instr.Offset + (uint)instr.GetSize() + (uint)reader.ReadSByte(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual object ReadShortInlineI(Instruction instr) { - if (instr.OpCode.Code == Code.Ldc_I4_S) - return reader.ReadSByte(); - return reader.ReadByte(); - } - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual float ReadShortInlineR(Instruction instr) => reader.ReadSingle(); - - /// - /// Reads a operand - /// - /// The current instruction - /// The operand - protected virtual IVariable ReadShortInlineVar(Instruction instr) { - if (IsArgOperandInstruction(instr)) - return ReadShortInlineVarArg(instr); - return ReadShortInlineVarLocal(instr); - } - - /// - /// Reads a (a parameter) operand - /// - /// The current instruction - /// The operand - 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) => GetLocal(reader.ReadByte()); - - /// - /// Returns true if it's one of the ldarg/starg instructions that have an operand - /// - /// The instruction to check - protected static bool IsArgOperandInstruction(Instruction instr) { - switch (instr.OpCode.Code) { - case Code.Ldarg: - case Code.Ldarg_S: - case Code.Ldarga: - case Code.Ldarga_S: - case Code.Starg: - case Code.Starg_S: - return true; - default: - return false; - } - } - - /// - /// Returns a parameter - /// - /// 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; - } - - /// - /// Returns a local - /// - /// 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; - } - - /// - /// Add an exception handler if it appears valid - /// - /// The exception handler - /// true if it was added, false otherwise - protected bool Add(ExceptionHandler eh) { - uint tryStart = GetOffset(eh.TryStart); - uint tryEnd = GetOffset(eh.TryEnd); - if (tryEnd <= tryStart) - return false; - - uint handlerStart = GetOffset(eh.HandlerStart); - uint handlerEnd = GetOffset(eh.HandlerEnd); - if (handlerEnd <= handlerStart) - return false; - - if (eh.IsFilter) { - if (eh.FilterStart is null) - return false; - if (eh.FilterStart.Offset >= handlerStart) - return false; - } - - if (handlerStart <= tryStart && tryStart < handlerEnd) - return false; - if (handlerStart < tryEnd && tryEnd <= handlerEnd) - return false; - - if (tryStart <= handlerStart && handlerStart < tryEnd) - return false; - if (tryStart < handlerEnd && handlerEnd <= tryEnd) - return false; - - // It's probably valid, so let's add it. - exceptionHandlers.Add(eh); - return true; - } - - /// - /// Gets the offset of an instruction - /// - /// The instruction or null if the offset is the first offset - /// at the end of the method. - /// The instruction offset - uint GetOffset(Instruction instr) { - if (instr is not null) - return instr.Offset; - var instructions = this.instructions; - if (instructions.Count == 0) - return 0; - return instructions[instructions.Count - 1].Offset; - } - - /// - /// Restores a 's body with the parsed method instructions - /// and exception handlers - /// - /// The method that gets updated with the instructions, locals, and - /// exception handlers. - public virtual void RestoreMethod(MethodDef method) { - var body = method.Body; - - body.Variables.Clear(); - var locals = this.locals; - if (locals is not null) { - 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 is not null) { - 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 is not null) { - int count = exceptionHandlers.Count; - for (int i = 0; i < count; i++) - body.ExceptionHandlers.Add(exceptionHandlers[i]); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/MethodTableToTypeConverter.cs b/Plugins/dnlib/DotNet/Emit/MethodTableToTypeConverter.cs deleted file mode 100644 index 38c05f3..0000000 --- a/Plugins/dnlib/DotNet/Emit/MethodTableToTypeConverter.cs +++ /dev/null @@ -1,156 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Reflection; -using System.Reflection.Emit; -using SR = System.Reflection; - -namespace dnlib.DotNet.Emit { - /// - /// Converts a type address to a . The address can be found in - /// RuntimeTypeHandle.Value and it's the same address you use with the WinDbg SOS command - /// !dumpmt. - /// - static class MethodTableToTypeConverter { - const string METHOD_NAME = "m"; - static readonly MethodInfo setMethodBodyMethodInfo = typeof(MethodBuilder).GetMethod("SetMethodBody", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - static readonly FieldInfo localSignatureFieldInfo = typeof(ILGenerator).GetField("m_localSignature", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - static readonly FieldInfo sigDoneFieldInfo = typeof(SignatureHelper).GetField("m_sigDone", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - static readonly FieldInfo currSigFieldInfo = typeof(SignatureHelper).GetField("m_currSig", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - static readonly FieldInfo signatureFieldInfo = typeof(SignatureHelper).GetField("m_signature", BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance); - static readonly FieldInfo ptrFieldInfo = typeof(RuntimeTypeHandle).GetField("m_ptr", BindingFlags.DeclaredOnly | BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public); - static readonly Dictionary addrToType = new Dictionary(); - static ModuleBuilder moduleBuilder; - static int numNewTypes; - static object lockObj = new object(); - - static MethodTableToTypeConverter() { - if (ptrFieldInfo is null) { -#if NETSTANDARD || NETCOREAPP - 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"); - } - - // 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); - } - - /// - /// Converts to a . - /// - /// Address of type - /// The or null - public static Type Convert(IntPtr address) { - lock (lockObj) { - if (addrToType.TryGetValue(address, out var type)) - return type; - - type = GetTypeNET20(address) ?? GetTypeUsingTypeBuilder(address); - addrToType[address] = type; - return type; - } - } - - static Type GetTypeUsingTypeBuilder(IntPtr address) { - 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 is not null) - return GetTypeNET45(tb, mb, address); - else - return GetTypeNET40(tb, mb, address); - } - catch { - moduleBuilder = null; - return null; - } - } - - // .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; - var locals = GetLocalSignature(address); - setMethodBodyMethodInfo.Invoke(mb, new object[5] { code, maxStack, locals, null, null }); -#if NETSTANDARD - 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; - } - - // 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(); - ilg.Emit(SR.Emit.OpCodes.Ret); - - // We need at least one local to make sure the SignatureHelper from ILGenerator is used. - ilg.DeclareLocal(typeof(int)); - - var locals = GetLocalSignature(address); - var sigHelper = (SignatureHelper)localSignatureFieldInfo.GetValue(ilg); - sigDoneFieldInfo.SetValue(sigHelper, true); - currSigFieldInfo.SetValue(sigHelper, locals.Length); - signatureFieldInfo.SetValue(sigHelper, locals); -#if NETSTANDARD - 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; - } - - // .NET Framework 2.0 - 3.5 - static Type GetTypeNET20(IntPtr address) { - if (ptrFieldInfo is null) - return null; - object th = new RuntimeTypeHandle(); - ptrFieldInfo.SetValue(th, address); - return Type.GetTypeFromHandle((RuntimeTypeHandle)th); - } - - static string GetNextTypeName() => $"Type{numNewTypes++}"; - - static byte[] GetLocalSignature(IntPtr mtAddr) { - ulong mtValue = (ulong)mtAddr.ToInt64(); - if (IntPtr.Size == 4) { - return new byte[] { - 0x07, - 0x01, - (byte)ElementType.Internal, - (byte)mtValue, - (byte)(mtValue >> 8), - (byte)(mtValue >> 16), - (byte)(mtValue >> 24), - }; - } - else { - return new byte[] { - 0x07, - 0x01, - (byte)ElementType.Internal, - (byte)mtValue, - (byte)(mtValue >> 8), - (byte)(mtValue >> 16), - (byte)(mtValue >> 24), - (byte)(mtValue >> 32), - (byte)(mtValue >> 40), - (byte)(mtValue >> 48), - (byte)(mtValue >> 56), - }; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/MethodUtils.cs b/Plugins/dnlib/DotNet/Emit/MethodUtils.cs deleted file mode 100644 index 5a2024d..0000000 --- a/Plugins/dnlib/DotNet/Emit/MethodUtils.cs +++ /dev/null @@ -1,516 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet.Emit { - /// - /// Instruction utility methods - /// - public static class MethodUtils { - /// - /// Shorter instructions are converted to the longer form, eg. Ldc_I4_1 is - /// converted to Ldc_I4 with a 1 as the operand. - /// - /// All instructions - /// All locals - /// 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) { - 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; - - case Code.Bge_Un_S: - instr.OpCode = OpCodes.Bge_Un; - break; - - case Code.Bgt_S: - instr.OpCode = OpCodes.Bgt; - break; - - case Code.Bgt_Un_S: - instr.OpCode = OpCodes.Bgt_Un; - break; - - case Code.Ble_S: - instr.OpCode = OpCodes.Ble; - break; - - case Code.Ble_Un_S: - instr.OpCode = OpCodes.Ble_Un; - break; - - case Code.Blt_S: - instr.OpCode = OpCodes.Blt; - break; - - case Code.Blt_Un_S: - instr.OpCode = OpCodes.Blt_Un; - break; - - case Code.Bne_Un_S: - instr.OpCode = OpCodes.Bne_Un; - break; - - case Code.Br_S: - instr.OpCode = OpCodes.Br; - break; - - case Code.Brfalse_S: - instr.OpCode = OpCodes.Brfalse; - break; - - case Code.Brtrue_S: - instr.OpCode = OpCodes.Brtrue; - break; - - case Code.Ldarg_0: - instr.OpCode = OpCodes.Ldarg; - instr.Operand = ReadList(parameters, 0); - break; - - case Code.Ldarg_1: - instr.OpCode = OpCodes.Ldarg; - instr.Operand = ReadList(parameters, 1); - break; - - case Code.Ldarg_2: - instr.OpCode = OpCodes.Ldarg; - instr.Operand = ReadList(parameters, 2); - break; - - case Code.Ldarg_3: - instr.OpCode = OpCodes.Ldarg; - instr.Operand = ReadList(parameters, 3); - break; - - case Code.Ldarg_S: - instr.OpCode = OpCodes.Ldarg; - break; - - case Code.Ldarga_S: - instr.OpCode = OpCodes.Ldarga; - break; - - case Code.Ldc_I4_0: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 0; - break; - - case Code.Ldc_I4_1: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 1; - break; - - case Code.Ldc_I4_2: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 2; - break; - - case Code.Ldc_I4_3: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 3; - break; - - case Code.Ldc_I4_4: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 4; - break; - - case Code.Ldc_I4_5: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 5; - break; - - case Code.Ldc_I4_6: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 6; - break; - - case Code.Ldc_I4_7: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 7; - break; - - case Code.Ldc_I4_8: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = 8; - break; - - case Code.Ldc_I4_M1: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = -1; - break; - - case Code.Ldc_I4_S: - instr.OpCode = OpCodes.Ldc_I4; - instr.Operand = (int)(sbyte)instr.Operand; - break; - - case Code.Ldloc_0: - instr.OpCode = OpCodes.Ldloc; - instr.Operand = ReadList(locals, 0); - break; - - case Code.Ldloc_1: - instr.OpCode = OpCodes.Ldloc; - instr.Operand = ReadList(locals, 1); - break; - - case Code.Ldloc_2: - instr.OpCode = OpCodes.Ldloc; - instr.Operand = ReadList(locals, 2); - break; - - case Code.Ldloc_3: - instr.OpCode = OpCodes.Ldloc; - instr.Operand = ReadList(locals, 3); - break; - - case Code.Ldloc_S: - instr.OpCode = OpCodes.Ldloc; - break; - - case Code.Ldloca_S: - instr.OpCode = OpCodes.Ldloca; - break; - - case Code.Leave_S: - instr.OpCode = OpCodes.Leave; - break; - - case Code.Starg_S: - instr.OpCode = OpCodes.Starg; - break; - - case Code.Stloc_0: - instr.OpCode = OpCodes.Stloc; - instr.Operand = ReadList(locals, 0); - break; - - case Code.Stloc_1: - instr.OpCode = OpCodes.Stloc; - instr.Operand = ReadList(locals, 1); - break; - - case Code.Stloc_2: - instr.OpCode = OpCodes.Stloc; - instr.Operand = ReadList(locals, 2); - break; - - case Code.Stloc_3: - instr.OpCode = OpCodes.Stloc; - instr.Operand = ReadList(locals, 3); - break; - - case Code.Stloc_S: - instr.OpCode = OpCodes.Stloc; - break; - } - } - } - - static T ReadList(IList list, int index) { - if (list is null) - return default; - if ((uint)index < (uint)list.Count) - return list[index]; - return default; - } - - /// - /// Optimizes instructions by using the shorter form if possible. Eg. Ldc_I4 1 - /// will be replaced with Ldc_I4_1. - /// - /// All instructions - public static void OptimizeMacros(this IList instructions) { - int count = instructions.Count; - for (int i = 0; i < count; i++) { - var instr = instructions[i]; - Parameter arg; - Local local; - switch (instr.OpCode.Code) { - case Code.Ldarg: - case Code.Ldarg_S: - arg = instr.Operand as Parameter; - if (arg is null) - break; - if (arg.Index == 0) { - instr.OpCode = OpCodes.Ldarg_0; - instr.Operand = null; - } - else if (arg.Index == 1) { - instr.OpCode = OpCodes.Ldarg_1; - instr.Operand = null; - } - else if (arg.Index == 2) { - instr.OpCode = OpCodes.Ldarg_2; - instr.Operand = null; - } - else if (arg.Index == 3) { - instr.OpCode = OpCodes.Ldarg_3; - instr.Operand = null; - } - else if (byte.MinValue <= arg.Index && arg.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Ldarg_S; - break; - - case Code.Ldarga: - arg = instr.Operand as Parameter; - if (arg is null) - break; - if (byte.MinValue <= arg.Index && arg.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Ldarga_S; - break; - - case Code.Ldc_I4: - case Code.Ldc_I4_S: - int i4; - if (instr.Operand is int) - i4 = (int)instr.Operand; - else if (instr.Operand is sbyte) - i4 = (sbyte)instr.Operand; - else - break; - switch (i4) { - case 0: - instr.OpCode = OpCodes.Ldc_I4_0; - instr.Operand = null; - break; - - case 1: - instr.OpCode = OpCodes.Ldc_I4_1; - instr.Operand = null; - break; - - case 2: - instr.OpCode = OpCodes.Ldc_I4_2; - instr.Operand = null; - break; - - case 3: - instr.OpCode = OpCodes.Ldc_I4_3; - instr.Operand = null; - break; - - case 4: - instr.OpCode = OpCodes.Ldc_I4_4; - instr.Operand = null; - break; - - case 5: - instr.OpCode = OpCodes.Ldc_I4_5; - instr.Operand = null; - break; - - case 6: - instr.OpCode = OpCodes.Ldc_I4_6; - instr.Operand = null; - break; - - case 7: - instr.OpCode = OpCodes.Ldc_I4_7; - instr.Operand = null; - break; - - case 8: - instr.OpCode = OpCodes.Ldc_I4_8; - instr.Operand = null; - break; - - case -1: - instr.OpCode = OpCodes.Ldc_I4_M1; - instr.Operand = null; - break; - - default: - if (sbyte.MinValue <= i4 && i4 <= sbyte.MaxValue) { - instr.OpCode = OpCodes.Ldc_I4_S; - instr.Operand = (sbyte)i4; - } - break; - } - break; - - case Code.Ldloc: - case Code.Ldloc_S: - local = instr.Operand as Local; - if (local is null) - break; - if (local.Index == 0) { - instr.OpCode = OpCodes.Ldloc_0; - instr.Operand = null; - } - else if (local.Index == 1) { - instr.OpCode = OpCodes.Ldloc_1; - instr.Operand = null; - } - else if (local.Index == 2) { - instr.OpCode = OpCodes.Ldloc_2; - instr.Operand = null; - } - else if (local.Index == 3) { - instr.OpCode = OpCodes.Ldloc_3; - instr.Operand = null; - } - else if (byte.MinValue <= local.Index && local.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Ldloc_S; - break; - - case Code.Ldloca: - local = instr.Operand as Local; - if (local is null) - break; - if (byte.MinValue <= local.Index && local.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Ldloca_S; - break; - - case Code.Starg: - arg = instr.Operand as Parameter; - if (arg is null) - break; - if (byte.MinValue <= arg.Index && arg.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Starg_S; - break; - - case Code.Stloc: - case Code.Stloc_S: - local = instr.Operand as Local; - if (local is null) - break; - if (local.Index == 0) { - instr.OpCode = OpCodes.Stloc_0; - instr.Operand = null; - } - else if (local.Index == 1) { - instr.OpCode = OpCodes.Stloc_1; - instr.Operand = null; - } - else if (local.Index == 2) { - instr.OpCode = OpCodes.Stloc_2; - instr.Operand = null; - } - else if (local.Index == 3) { - instr.OpCode = OpCodes.Stloc_3; - instr.Operand = null; - } - else if (byte.MinValue <= local.Index && local.Index <= byte.MaxValue) - instr.OpCode = OpCodes.Stloc_S; - break; - } - } - - OptimizeBranches(instructions); - } - - /// - /// Short branch instructions are converted to the long form, eg. Beq_S is - /// converted to Beq. - /// - /// All instructions - public static void SimplifyBranches(this IList 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; - case Code.Bgt_S: instr.OpCode = OpCodes.Bgt; break; - case Code.Ble_S: instr.OpCode = OpCodes.Ble; break; - case Code.Blt_S: instr.OpCode = OpCodes.Blt; break; - case Code.Bne_Un_S: instr.OpCode = OpCodes.Bne_Un; break; - case Code.Bge_Un_S: instr.OpCode = OpCodes.Bge_Un; break; - case Code.Bgt_Un_S: instr.OpCode = OpCodes.Bgt_Un; break; - case Code.Ble_Un_S: instr.OpCode = OpCodes.Ble_Un; break; - case Code.Blt_Un_S: instr.OpCode = OpCodes.Blt_Un; break; - case Code.Br_S: instr.OpCode = OpCodes.Br; break; - case Code.Brfalse_S:instr.OpCode = OpCodes.Brfalse; break; - case Code.Brtrue_S: instr.OpCode = OpCodes.Brtrue; break; - case Code.Leave_S: instr.OpCode = OpCodes.Leave; break; - } - } - } - - /// - /// Optimizes branches by using the smallest possible branch - /// - /// All instructions - public static void OptimizeBranches(this IList instructions) { - while (true) { - UpdateInstructionOffsets(instructions); - - bool modified = false; - 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; - case Code.Bge: shortOpCode = OpCodes.Bge_S; break; - case Code.Bge_Un: shortOpCode = OpCodes.Bge_Un_S; break; - case Code.Bgt: shortOpCode = OpCodes.Bgt_S; break; - case Code.Bgt_Un: shortOpCode = OpCodes.Bgt_Un_S; break; - case Code.Ble: shortOpCode = OpCodes.Ble_S; break; - case Code.Ble_Un: shortOpCode = OpCodes.Ble_Un_S; break; - case Code.Blt: shortOpCode = OpCodes.Blt_S; break; - case Code.Blt_Un: shortOpCode = OpCodes.Blt_Un_S; break; - case Code.Bne_Un: shortOpCode = OpCodes.Bne_Un_S; break; - case Code.Br: shortOpCode = OpCodes.Br_S; break; - case Code.Brfalse: shortOpCode = OpCodes.Brfalse_S; break; - case Code.Brtrue: shortOpCode = OpCodes.Brtrue_S; break; - case Code.Leave: shortOpCode = OpCodes.Leave_S; break; - default: continue; - } - var targetInstr = instr.Operand as Instruction; - if (targetInstr is null) - continue; - - int afterShortInstr; - if (targetInstr.Offset >= instr.Offset) { - // Target is >= this instruction so use the offset after - // current instruction - afterShortInstr = (int)instr.Offset + instr.GetSize(); - } - else { - // Target is < this instruction so use the offset after - // the short instruction - const int operandSize = 1; - afterShortInstr = (int)instr.Offset + shortOpCode.Size + operandSize; - } - - int displ = (int)targetInstr.Offset - afterShortInstr; - if (sbyte.MinValue <= displ && displ <= sbyte.MaxValue) { - instr.OpCode = shortOpCode; - modified = true; - } - } - if (!modified) - break; - } - } - - /// - /// Updates each instruction's offset - /// - /// All instructions - /// Total size in bytes of all instructions - public static uint UpdateInstructionOffsets(this IList instructions) { - uint offset = 0; - int count = instructions.Count; - for (int i = 0; i < count; i++) { - var instr = instructions[i]; - instr.Offset = offset; - offset += (uint)instr.GetSize(); - } - return offset; - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/OpCode.cs b/Plugins/dnlib/DotNet/Emit/OpCode.cs deleted file mode 100644 index d5e315f..0000000 --- a/Plugins/dnlib/DotNet/Emit/OpCode.cs +++ /dev/null @@ -1,213 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet.Emit { - /// - /// A CIL opcode - /// - public sealed class OpCode { - /// - /// The opcode name - /// - public readonly string Name; - - /// - /// The opcode as a enum - /// - public readonly Code Code; - - /// - /// Operand type - /// - public readonly OperandType OperandType; - - /// - /// Flow control info - /// - public readonly FlowControl FlowControl; - - /// - /// Opcode type - /// - public readonly OpCodeType OpCodeType; - - /// - /// Push stack behavior - /// - public readonly StackBehaviour StackBehaviourPush; - - /// - /// Pop stack behavior - /// - public readonly StackBehaviour StackBehaviourPop; - - /// - /// Gets the value which is compatible with - /// - public short Value => (short)Code; - - /// - /// Gets the size of the opcode. It's either 1 or 2 bytes. - /// - public int Size => Code < (Code)0x100 || Code == Code.UNKNOWN1 ? 1 : 2; - - /// - /// 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; - FlowControl = flowControl; - OpCodeType = opCodeType; - StackBehaviourPush = push; - StackBehaviourPop = pop; - if (!experimental) { - if (((ushort)code >> 8) == 0) - OpCodes.OneByteOpCodes[(byte)code] = this; - else if (((ushort)code >> 8) == 0xFE) - OpCodes.TwoByteOpCodes[(byte)code] = this; - } - } - - /// - /// Creates a new instruction with no operand - /// - /// A new instance - public Instruction ToInstruction() => Instruction.Create(this); - - /// - /// Creates a new instruction with a operand - /// - /// The value - /// A new instance - 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) => Instruction.Create(this, value); - - /// - /// Creates a new instruction with an operand - /// - /// The value - /// A new instance - 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) => Instruction.Create(this, value); - - /// - /// Creates a new instruction with a operand - /// - /// The value - /// A new instance - 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) => Instruction.Create(this, value); - - /// - /// Creates a new instruction with a string operand - /// - /// The string - /// A new instance - 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) => Instruction.Create(this, target); - - /// - /// Creates a new instruction with an instruction target list operand - /// - /// The targets - /// A new instance - public Instruction ToInstruction(IList targets) => Instruction.Create(this, targets); - - /// - /// Creates a new instruction with a type operand - /// - /// The type - /// A new instance - 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) => 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) => Instruction.Create(this, mr); - - /// - /// Creates a new instruction with a field operand - /// - /// The field - /// A new instance - 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) => Instruction.Create(this, method); - - /// - /// Creates a new instruction with a token operand - /// - /// The token - /// A new instance - 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) => Instruction.Create(this, methodSig); - - /// - /// Creates a new instruction with a method parameter operand - /// - /// The method parameter - /// A new instance - 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) => Instruction.Create(this, local); - - /// - public override string ToString() => Name; - } -} diff --git a/Plugins/dnlib/DotNet/Emit/OpCodeType.cs b/Plugins/dnlib/DotNet/Emit/OpCodeType.cs deleted file mode 100644 index 6af8b86..0000000 --- a/Plugins/dnlib/DotNet/Emit/OpCodeType.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// CIL opcode type - /// - public enum OpCodeType : byte { - /// - Annotation, - /// - Macro, - /// - Nternal, - /// - Objmodel, - /// - Prefix, - /// - Primitive, - /// - Experimental, - } -} diff --git a/Plugins/dnlib/DotNet/Emit/OpCodes.cs b/Plugins/dnlib/DotNet/Emit/OpCodes.cs deleted file mode 100644 index 639f9c4..0000000 --- a/Plugins/dnlib/DotNet/Emit/OpCodes.cs +++ /dev/null @@ -1,263 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// Contains all valid CIL opcodes - /// - public static class OpCodes { - /// - /// All one-byte opcodes - /// - public static readonly OpCode[] OneByteOpCodes = new OpCode[0x100]; - - /// - /// All two-byte opcodes (first byte is 0xFE) - /// - public static readonly OpCode[] TwoByteOpCodes = new OpCode[0x100]; - -#pragma warning disable 1591 // disable XML doc warning - public static readonly OpCode UNKNOWN1 = new OpCode("UNKNOWN1", Code.UNKNOWN1, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode UNKNOWN2 = new OpCode("UNKNOWN2", Code.UNKNOWN2, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Nop = new OpCode("nop", Code.Nop, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Break = new OpCode("break", Code.Break, OperandType.InlineNone, FlowControl.Break, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Ldarg_0 = new OpCode("ldarg.0", Code.Ldarg_0, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldarg_1 = new OpCode("ldarg.1", Code.Ldarg_1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldarg_2 = new OpCode("ldarg.2", Code.Ldarg_2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldarg_3 = new OpCode("ldarg.3", Code.Ldarg_3, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloc_0 = new OpCode("ldloc.0", Code.Ldloc_0, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloc_1 = new OpCode("ldloc.1", Code.Ldloc_1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloc_2 = new OpCode("ldloc.2", Code.Ldloc_2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloc_3 = new OpCode("ldloc.3", Code.Ldloc_3, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Stloc_0 = new OpCode("stloc.0", Code.Stloc_0, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Stloc_1 = new OpCode("stloc.1", Code.Stloc_1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Stloc_2 = new OpCode("stloc.2", Code.Stloc_2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Stloc_3 = new OpCode("stloc.3", Code.Stloc_3, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Ldarg_S = new OpCode("ldarg.s", Code.Ldarg_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldarga_S = new OpCode("ldarga.s", Code.Ldarga_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Starg_S = new OpCode("starg.s", Code.Starg_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Ldloc_S = new OpCode("ldloc.s", Code.Ldloc_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloca_S = new OpCode("ldloca.s", Code.Ldloca_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Stloc_S = new OpCode("stloc.s", Code.Stloc_S, OperandType.ShortInlineVar, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Ldnull = new OpCode("ldnull", Code.Ldnull, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushref, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_M1 = new OpCode("ldc.i4.m1", Code.Ldc_I4_M1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_0 = new OpCode("ldc.i4.0", Code.Ldc_I4_0, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_1 = new OpCode("ldc.i4.1", Code.Ldc_I4_1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_2 = new OpCode("ldc.i4.2", Code.Ldc_I4_2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_3 = new OpCode("ldc.i4.3", Code.Ldc_I4_3, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_4 = new OpCode("ldc.i4.4", Code.Ldc_I4_4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_5 = new OpCode("ldc.i4.5", Code.Ldc_I4_5, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_6 = new OpCode("ldc.i4.6", Code.Ldc_I4_6, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_7 = new OpCode("ldc.i4.7", Code.Ldc_I4_7, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_8 = new OpCode("ldc.i4.8", Code.Ldc_I4_8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4_S = new OpCode("ldc.i4.s", Code.Ldc_I4_S, OperandType.ShortInlineI, FlowControl.Next, OpCodeType.Macro, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I4 = new OpCode("ldc.i4", Code.Ldc_I4, OperandType.InlineI, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldc_I8 = new OpCode("ldc.i8", Code.Ldc_I8, OperandType.InlineI8, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop0); - public static readonly OpCode Ldc_R4 = new OpCode("ldc.r4", Code.Ldc_R4, OperandType.ShortInlineR, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr4, StackBehaviour.Pop0); - public static readonly OpCode Ldc_R8 = new OpCode("ldc.r8", Code.Ldc_R8, OperandType.InlineR, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr8, StackBehaviour.Pop0); - public static readonly OpCode Dup = new OpCode("dup", Code.Dup, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1_push1, StackBehaviour.Pop1); - public static readonly OpCode Pop = new OpCode("pop", Code.Pop, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Jmp = new OpCode("jmp", Code.Jmp, OperandType.InlineMethod, FlowControl.Call, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Call = new OpCode("call", Code.Call, OperandType.InlineMethod, FlowControl.Call, OpCodeType.Primitive, StackBehaviour.Varpush, StackBehaviour.Varpop); - public static readonly OpCode Calli = new OpCode("calli", Code.Calli, OperandType.InlineSig, FlowControl.Call, OpCodeType.Primitive, StackBehaviour.Varpush, StackBehaviour.Varpop); - public static readonly OpCode Ret = new OpCode("ret", Code.Ret, OperandType.InlineNone, FlowControl.Return, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Varpop); - public static readonly OpCode Br_S = new OpCode("br.s", Code.Br_S, OperandType.ShortInlineBrTarget, FlowControl.Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Brfalse_S = new OpCode("brfalse.s", Code.Brfalse_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Brtrue_S = new OpCode("brtrue.s", Code.Brtrue_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Beq_S = new OpCode("beq.s", Code.Beq_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bge_S = new OpCode("bge.s", Code.Bge_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bgt_S = new OpCode("bgt.s", Code.Bgt_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Ble_S = new OpCode("ble.s", Code.Ble_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Blt_S = new OpCode("blt.s", Code.Blt_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bne_Un_S = new OpCode("bne.un.s", Code.Bne_Un_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bge_Un_S = new OpCode("bge.un.s", Code.Bge_Un_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bgt_Un_S = new OpCode("bgt.un.s", Code.Bgt_Un_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Ble_Un_S = new OpCode("ble.un.s", Code.Ble_Un_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Blt_Un_S = new OpCode("blt.un.s", Code.Blt_Un_S, OperandType.ShortInlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Br = new OpCode("br", Code.Br, OperandType.InlineBrTarget, FlowControl.Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Brfalse = new OpCode("brfalse", Code.Brfalse, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Brtrue = new OpCode("brtrue", Code.Brtrue, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Beq = new OpCode("beq", Code.Beq, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bge = new OpCode("bge", Code.Bge, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bgt = new OpCode("bgt", Code.Bgt, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Ble = new OpCode("ble", Code.Ble, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Blt = new OpCode("blt", Code.Blt, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bne_Un = new OpCode("bne.un", Code.Bne_Un, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bge_Un = new OpCode("bge.un", Code.Bge_Un, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Bgt_Un = new OpCode("bgt.un", Code.Bgt_Un, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Ble_Un = new OpCode("ble.un", Code.Ble_Un, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Blt_Un = new OpCode("blt.un", Code.Blt_Un, OperandType.InlineBrTarget, FlowControl.Cond_Branch, OpCodeType.Macro, StackBehaviour.Push0, StackBehaviour.Pop1_pop1); - public static readonly OpCode Switch = new OpCode("switch", Code.Switch, OperandType.InlineSwitch, FlowControl.Cond_Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Ldind_I1 = new OpCode("ldind.i1", Code.Ldind_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_U1 = new OpCode("ldind.u1", Code.Ldind_U1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_I2 = new OpCode("ldind.i2", Code.Ldind_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_U2 = new OpCode("ldind.u2", Code.Ldind_U2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_I4 = new OpCode("ldind.i4", Code.Ldind_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_U4 = new OpCode("ldind.u4", Code.Ldind_U4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_I8 = new OpCode("ldind.i8", Code.Ldind_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Popi); - public static readonly OpCode Ldind_I = new OpCode("ldind.i", Code.Ldind_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Ldind_R4 = new OpCode("ldind.r4", Code.Ldind_R4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr4, StackBehaviour.Popi); - public static readonly OpCode Ldind_R8 = new OpCode("ldind.r8", Code.Ldind_R8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr8, StackBehaviour.Popi); - public static readonly OpCode Ldind_Ref = new OpCode("ldind.ref", Code.Ldind_Ref, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushref, StackBehaviour.Popi); - public static readonly OpCode Stind_Ref = new OpCode("stind.ref", Code.Stind_Ref, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Stind_I1 = new OpCode("stind.i1", Code.Stind_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Stind_I2 = new OpCode("stind.i2", Code.Stind_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Stind_I4 = new OpCode("stind.i4", Code.Stind_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Stind_I8 = new OpCode("stind.i8", Code.Stind_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi8); - public static readonly OpCode Stind_R4 = new OpCode("stind.r4", Code.Stind_R4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popr4); - public static readonly OpCode Stind_R8 = new OpCode("stind.r8", Code.Stind_R8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popr8); - public static readonly OpCode Add = new OpCode("add", Code.Add, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Sub = new OpCode("sub", Code.Sub, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Mul = new OpCode("mul", Code.Mul, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Div = new OpCode("div", Code.Div, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Div_Un = new OpCode("div.un", Code.Div_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Rem = new OpCode("rem", Code.Rem, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Rem_Un = new OpCode("rem.un", Code.Rem_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode And = new OpCode("and", Code.And, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Or = new OpCode("or", Code.Or, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Xor = new OpCode("xor", Code.Xor, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Shl = new OpCode("shl", Code.Shl, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Shr = new OpCode("shr", Code.Shr, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Shr_Un = new OpCode("shr.un", Code.Shr_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Neg = new OpCode("neg", Code.Neg, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1); - public static readonly OpCode Not = new OpCode("not", Code.Not, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1); - public static readonly OpCode Conv_I1 = new OpCode("conv.i1", Code.Conv_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_I2 = new OpCode("conv.i2", Code.Conv_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_I4 = new OpCode("conv.i4", Code.Conv_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_I8 = new OpCode("conv.i8", Code.Conv_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Conv_R4 = new OpCode("conv.r4", Code.Conv_R4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr4, StackBehaviour.Pop1); - public static readonly OpCode Conv_R8 = new OpCode("conv.r8", Code.Conv_R8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr8, StackBehaviour.Pop1); - public static readonly OpCode Conv_U4 = new OpCode("conv.u4", Code.Conv_U4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_U8 = new OpCode("conv.u8", Code.Conv_U8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Callvirt = new OpCode("callvirt", Code.Callvirt, OperandType.InlineMethod, FlowControl.Call, OpCodeType.Objmodel, StackBehaviour.Varpush, StackBehaviour.Varpop); - public static readonly OpCode Cpobj = new OpCode("cpobj", Code.Cpobj, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Ldobj = new OpCode("ldobj", Code.Ldobj, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push1, StackBehaviour.Popi); - public static readonly OpCode Ldstr = new OpCode("ldstr", Code.Ldstr, OperandType.InlineString, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushref, StackBehaviour.Pop0); - public static readonly OpCode Newobj = new OpCode("newobj", Code.Newobj, OperandType.InlineMethod, FlowControl.Call, OpCodeType.Objmodel, StackBehaviour.Pushref, StackBehaviour.Varpop); - public static readonly OpCode Castclass = new OpCode("castclass", Code.Castclass, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushref, StackBehaviour.Popref); - public static readonly OpCode Isinst = new OpCode("isinst", Code.Isinst, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref); - public static readonly OpCode Conv_R_Un = new OpCode("conv.r.un", Code.Conv_R_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr8, StackBehaviour.Pop1); - public static readonly OpCode Unbox = new OpCode("unbox", Code.Unbox, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popref); - public static readonly OpCode Throw = new OpCode("throw", Code.Throw, OperandType.InlineNone, FlowControl.Throw, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref); - public static readonly OpCode Ldfld = new OpCode("ldfld", Code.Ldfld, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push1, StackBehaviour.Popref); - public static readonly OpCode Ldflda = new OpCode("ldflda", Code.Ldflda, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref); - public static readonly OpCode Stfld = new OpCode("stfld", Code.Stfld, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_pop1); - public static readonly OpCode Ldsfld = new OpCode("ldsfld", Code.Ldsfld, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldsflda = new OpCode("ldsflda", Code.Ldsflda, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Stsfld = new OpCode("stsfld", Code.Stsfld, OperandType.InlineField, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Stobj = new OpCode("stobj", Code.Stobj, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_pop1); - public static readonly OpCode Conv_Ovf_I1_Un= new OpCode("conv.ovf.i1.un", Code.Conv_Ovf_I1_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I2_Un= new OpCode("conv.ovf.i2.un", Code.Conv_Ovf_I2_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I4_Un= new OpCode("conv.ovf.i4.un", Code.Conv_Ovf_I4_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I8_Un= new OpCode("conv.ovf.i8.un", Code.Conv_Ovf_I8_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U1_Un= new OpCode("conv.ovf.u1.un", Code.Conv_Ovf_U1_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U2_Un= new OpCode("conv.ovf.u2.un", Code.Conv_Ovf_U2_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U4_Un= new OpCode("conv.ovf.u4.un", Code.Conv_Ovf_U4_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U8_Un= new OpCode("conv.ovf.u8.un", Code.Conv_Ovf_U8_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I_Un = new OpCode("conv.ovf.i.un", Code.Conv_Ovf_I_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U_Un = new OpCode("conv.ovf.u.un", Code.Conv_Ovf_U_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Box = new OpCode("box", Code.Box, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushref, StackBehaviour.Pop1); - public static readonly OpCode Newarr = new OpCode("newarr", Code.Newarr, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushref, StackBehaviour.Popi); - public static readonly OpCode Ldlen = new OpCode("ldlen", Code.Ldlen, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref); - public static readonly OpCode Ldelema = new OpCode("ldelema", Code.Ldelema, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_I1 = new OpCode("ldelem.i1", Code.Ldelem_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_U1 = new OpCode("ldelem.u1", Code.Ldelem_U1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_I2 = new OpCode("ldelem.i2", Code.Ldelem_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_U2 = new OpCode("ldelem.u2", Code.Ldelem_U2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_I4 = new OpCode("ldelem.i4", Code.Ldelem_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_U4 = new OpCode("ldelem.u4", Code.Ldelem_U4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_I8 = new OpCode("ldelem.i8", Code.Ldelem_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi8, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_I = new OpCode("ldelem.i", Code.Ldelem_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushi, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_R4 = new OpCode("ldelem.r4", Code.Ldelem_R4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushr4, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_R8 = new OpCode("ldelem.r8", Code.Ldelem_R8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushr8, StackBehaviour.Popref_popi); - public static readonly OpCode Ldelem_Ref = new OpCode("ldelem.ref", Code.Ldelem_Ref, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Pushref, StackBehaviour.Popref_popi); - public static readonly OpCode Stelem_I = new OpCode("stelem.i", Code.Stelem_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popi); - public static readonly OpCode Stelem_I1 = new OpCode("stelem.i1", Code.Stelem_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popi); - public static readonly OpCode Stelem_I2 = new OpCode("stelem.i2", Code.Stelem_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popi); - public static readonly OpCode Stelem_I4 = new OpCode("stelem.i4", Code.Stelem_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popi); - public static readonly OpCode Stelem_I8 = new OpCode("stelem.i8", Code.Stelem_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popi8); - public static readonly OpCode Stelem_R4 = new OpCode("stelem.r4", Code.Stelem_R4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popr4); - public static readonly OpCode Stelem_R8 = new OpCode("stelem.r8", Code.Stelem_R8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popr8); - public static readonly OpCode Stelem_Ref = new OpCode("stelem.ref", Code.Stelem_Ref, OperandType.InlineNone, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_popref); - public static readonly OpCode Ldelem = new OpCode("ldelem", Code.Ldelem, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push1, StackBehaviour.Popref_popi); - public static readonly OpCode Stelem = new OpCode("stelem", Code.Stelem, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popref_popi_pop1); - public static readonly OpCode Unbox_Any = new OpCode("unbox.any", Code.Unbox_Any, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push1, StackBehaviour.Popref); - public static readonly OpCode Conv_Ovf_I1 = new OpCode("conv.ovf.i1", Code.Conv_Ovf_I1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U1 = new OpCode("conv.ovf.u1", Code.Conv_Ovf_U1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I2 = new OpCode("conv.ovf.i2", Code.Conv_Ovf_I2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U2 = new OpCode("conv.ovf.u2", Code.Conv_Ovf_U2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I4 = new OpCode("conv.ovf.i4", Code.Conv_Ovf_I4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U4 = new OpCode("conv.ovf.u4", Code.Conv_Ovf_U4, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I8 = new OpCode("conv.ovf.i8", Code.Conv_Ovf_I8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U8 = new OpCode("conv.ovf.u8", Code.Conv_Ovf_U8, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi8, StackBehaviour.Pop1); - public static readonly OpCode Refanyval = new OpCode("refanyval", Code.Refanyval, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Ckfinite = new OpCode("ckfinite", Code.Ckfinite, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushr8, StackBehaviour.Pop1); - public static readonly OpCode Mkrefany = new OpCode("mkrefany", Code.Mkrefany, OperandType.InlineType, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Popi); - public static readonly OpCode Ldtoken = new OpCode("ldtoken", Code.Ldtoken, OperandType.InlineTok, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Conv_U2 = new OpCode("conv.u2", Code.Conv_U2, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_U1 = new OpCode("conv.u1", Code.Conv_U1, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_I = new OpCode("conv.i", Code.Conv_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_I = new OpCode("conv.ovf.i", Code.Conv_Ovf_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Conv_Ovf_U = new OpCode("conv.ovf.u", Code.Conv_Ovf_U, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Add_Ovf = new OpCode("add.ovf", Code.Add_Ovf, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Add_Ovf_Un = new OpCode("add.ovf.un", Code.Add_Ovf_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Mul_Ovf = new OpCode("mul.ovf", Code.Mul_Ovf, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Mul_Ovf_Un = new OpCode("mul.ovf.un", Code.Mul_Ovf_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Sub_Ovf = new OpCode("sub.ovf", Code.Sub_Ovf, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Sub_Ovf_Un = new OpCode("sub.ovf.un", Code.Sub_Ovf_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop1_pop1); - public static readonly OpCode Endfinally = new OpCode("endfinally", Code.Endfinally, OperandType.InlineNone, FlowControl.Return, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.PopAll); - public static readonly OpCode Leave = new OpCode("leave", Code.Leave, OperandType.InlineBrTarget, FlowControl.Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.PopAll); - public static readonly OpCode Leave_S = new OpCode("leave.s", Code.Leave_S, OperandType.ShortInlineBrTarget, FlowControl.Branch, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.PopAll); - public static readonly OpCode Stind_I = new OpCode("stind.i", Code.Stind_I, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi_popi); - public static readonly OpCode Conv_U = new OpCode("conv.u", Code.Conv_U, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1); - public static readonly OpCode Prefix7 = new OpCode("prefix7", Code.Prefix7, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix6 = new OpCode("prefix6", Code.Prefix6, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix5 = new OpCode("prefix5", Code.Prefix5, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix4 = new OpCode("prefix4", Code.Prefix4, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix3 = new OpCode("prefix3", Code.Prefix3, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix2 = new OpCode("prefix2", Code.Prefix2, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefix1 = new OpCode("prefix1", Code.Prefix1, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Prefixref = new OpCode("prefixref", Code.Prefixref, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Nternal, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Arglist = new OpCode("arglist", Code.Arglist, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ceq = new OpCode("ceq", Code.Ceq, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1_pop1); - public static readonly OpCode Cgt = new OpCode("cgt", Code.Cgt, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1_pop1); - public static readonly OpCode Cgt_Un = new OpCode("cgt.un", Code.Cgt_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1_pop1); - public static readonly OpCode Clt = new OpCode("clt", Code.Clt, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1_pop1); - public static readonly OpCode Clt_Un = new OpCode("clt.un", Code.Clt_Un, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop1_pop1); - public static readonly OpCode Ldftn = new OpCode("ldftn", Code.Ldftn, OperandType.InlineMethod, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Ldvirtftn = new OpCode("ldvirtftn", Code.Ldvirtftn, OperandType.InlineMethod, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popref); - public static readonly OpCode Ldarg = new OpCode("ldarg", Code.Ldarg, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldarga = new OpCode("ldarga", Code.Ldarga, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Starg = new OpCode("starg", Code.Starg, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Ldloc = new OpCode("ldloc", Code.Ldloc, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push1, StackBehaviour.Pop0); - public static readonly OpCode Ldloca = new OpCode("ldloca", Code.Ldloca, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Pop0); - public static readonly OpCode Stloc = new OpCode("stloc", Code.Stloc, OperandType.InlineVar, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Pop1); - public static readonly OpCode Localloc = new OpCode("localloc", Code.Localloc, OperandType.InlineNone, FlowControl.Next, OpCodeType.Primitive, StackBehaviour.Pushi, StackBehaviour.Popi); - public static readonly OpCode Endfilter = new OpCode("endfilter", Code.Endfilter, OperandType.InlineNone, FlowControl.Return, OpCodeType.Primitive, StackBehaviour.Push0, StackBehaviour.Popi); - public static readonly OpCode Unaligned = new OpCode("unaligned.", Code.Unaligned, OperandType.ShortInlineI, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Volatile = new OpCode("volatile.", Code.Volatile, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Tailcall = new OpCode("tail.", Code.Tailcall, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); - public static readonly OpCode Initobj = new OpCode("initobj", Code.Initobj, OperandType.InlineType, FlowControl.Next, OpCodeType.Objmodel, StackBehaviour.Push0, StackBehaviour.Popi); - 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 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); - public static readonly OpCode Readonly = new OpCode("readonly.", Code.Readonly, OperandType.InlineNone, FlowControl.Meta, OpCodeType.Prefix, StackBehaviour.Push0, StackBehaviour.Pop0); -#pragma warning restore - - 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] is null) - OneByteOpCodes[i] = UNKNOWN1; - } - for (int i = 0; i < TwoByteOpCodes.Length; i++) { - if (TwoByteOpCodes[i] is null) - TwoByteOpCodes[i] = UNKNOWN2; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Emit/OperandType.cs b/Plugins/dnlib/DotNet/Emit/OperandType.cs deleted file mode 100644 index f4fe42f..0000000 --- a/Plugins/dnlib/DotNet/Emit/OperandType.cs +++ /dev/null @@ -1,53 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Emit { - /// - /// CIL opcode operand type - /// - public enum OperandType : byte { - /// 4-byte relative instruction offset - InlineBrTarget, - /// 4-byte field token ( or ) - InlineField, - /// int32 - InlineI, - /// int64 - InlineI8, - /// 4-byte method token (, - /// or ) - InlineMethod, - /// No operand - InlineNone, - /// Never used - InlinePhi, - /// 64-bit real - InlineR, - /// - NOT_USED_8, - /// 4-byte method sig token () - InlineSig, - /// 4-byte string token (0x70xxxxxx) - InlineString, - /// 4-byte count N followed by N 4-byte relative instruction offsets - InlineSwitch, - /// 4-byte token (, , - /// , , , - /// or ) - InlineTok, - /// 4-byte type token (, or - /// ) - InlineType, - /// 2-byte param/local index - InlineVar, - /// 1-byte relative instruction offset - ShortInlineBrTarget, - /// 1-byte sbyte () or byte (the rest) - ShortInlineI, - /// 32-bit real - ShortInlineR, - /// 1-byte param/local index - ShortInlineVar, - } -} diff --git a/Plugins/dnlib/DotNet/Emit/StackBehaviour.cs b/Plugins/dnlib/DotNet/Emit/StackBehaviour.cs deleted file mode 100644 index 37e3231..0000000 --- a/Plugins/dnlib/DotNet/Emit/StackBehaviour.cs +++ /dev/null @@ -1,69 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Emit { - /// - /// CIL opcode stack behavior - /// - public enum StackBehaviour : byte { - /// - Pop0, - /// - Pop1, - /// - Pop1_pop1, - /// - Popi, - /// - Popi_pop1, - /// - Popi_popi, - /// - Popi_popi8, - /// - Popi_popi_popi, - /// - Popi_popr4, - /// - Popi_popr8, - /// - Popref, - /// - Popref_pop1, - /// - Popref_popi, - /// - Popref_popi_popi, - /// - Popref_popi_popi8, - /// - Popref_popi_popr4, - /// - Popref_popi_popr8, - /// - Popref_popi_popref, - /// - Push0, - /// - Push1, - /// - Push1_push1, - /// - Pushi, - /// - Pushi8, - /// - Pushr4, - /// - Pushr8, - /// - Pushref, - /// - Varpop, - /// - Varpush, - /// - Popref_popi_pop1, - /// - PopAll = 0xFF, - } -} diff --git a/Plugins/dnlib/DotNet/EventAttributes.cs b/Plugins/dnlib/DotNet/EventAttributes.cs deleted file mode 100644 index abe9ac8..0000000 --- a/Plugins/dnlib/DotNet/EventAttributes.cs +++ /dev/null @@ -1,16 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Event attributes, see CorHdr.h/CorEventAttr - /// - [Flags] - public enum EventAttributes : ushort { - /// event is special. Name describes how. - SpecialName = 0x0200, - /// Runtime(metadata internal APIs) should check name encoding. - RTSpecialName = 0x0400, - } -} diff --git a/Plugins/dnlib/DotNet/EventDef.cs b/Plugins/dnlib/DotNet/EventDef.cs deleted file mode 100644 index b299136..0000000 --- a/Plugins/dnlib/DotNet/EventDef.cs +++ /dev/null @@ -1,416 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Event table - /// - public abstract class EventDef : IHasCustomAttribute, IHasSemantic, IHasCustomDebugInformation, IFullName, IMemberDef { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.Event, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 10; - - /// - public int HasSemanticTag => 0; - - /// - /// From column Event.EventFlags - /// - public EventAttributes Attributes { - get => (EventAttributes)attributes; - set => attributes = (int)value; - } - /// - protected int attributes; - - /// - /// From column Event.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column Event.EventType - /// - public ITypeDefOrRef EventType { - get => eventType; - set => eventType = value; - } - /// - protected ITypeDefOrRef eventType; - - /// - /// 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 int HasCustomDebugInformationTag => 10; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Gets/sets the adder method - /// - public MethodDef AddMethod { - get { - if (otherMethods is null) - InitializeEventMethods(); - return addMethod; - } - set { - if (otherMethods is null) - InitializeEventMethods(); - addMethod = value; - } - } - - /// - /// Gets/sets the invoker method - /// - public MethodDef InvokeMethod { - get { - if (otherMethods is null) - InitializeEventMethods(); - return invokeMethod; - } - set { - if (otherMethods is null) - InitializeEventMethods(); - invokeMethod = value; - } - } - - /// - /// Gets/sets the remover method - /// - public MethodDef RemoveMethod { - get { - if (otherMethods is null) - InitializeEventMethods(); - return removeMethod; - } - set { - if (otherMethods is null) - InitializeEventMethods(); - removeMethod = value; - } - } - - /// - /// Gets the other methods - /// - public IList OtherMethods { - get { - if (otherMethods is null) - InitializeEventMethods(); - return otherMethods; - } - } - - void InitializeEventMethods() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (otherMethods is null) - InitializeEventMethods_NoLock(); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Initializes , , - /// and . - /// - protected virtual void InitializeEventMethods_NoLock() => - otherMethods = new List(); - - /// - protected MethodDef addMethod; - /// - protected MethodDef invokeMethod; - /// - protected MethodDef removeMethod; - /// - protected IList otherMethods; - - /// Reset , , , - protected void ResetMethods() => otherMethods = null; - - /// - /// true if there are no methods attached to this event - /// - public bool IsEmpty => - // The first property access initializes the other fields we access here - AddMethod is null && - removeMethod is null && - invokeMethod is null && - otherMethods.Count == 0; - - /// - public bool HasCustomAttributes => CustomAttributes.Count > 0; - - /// - /// true if is not empty - /// - public bool HasOtherMethods => OtherMethods.Count > 0; - - /// - /// Gets/sets the declaring type (owner type) - /// - public TypeDef DeclaringType { - get => declaringType2; - set { - var currentDeclaringType = DeclaringType2; - if (currentDeclaringType == value) - return; - if (currentDeclaringType is not null) - currentDeclaringType.Events.Remove(this); // Will set DeclaringType2 = null - if (value is not null) - value.Events.Add(this); // Will set DeclaringType2 = value - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; - - /// - /// Called by and should normally not be called by any user - /// code. Use instead. Only call this if you must set the - /// declaring type without inserting it in the declaring type's method list. - /// - public TypeDef DeclaringType2 { - get => declaringType2; - set => declaringType2 = value; - } - /// - protected TypeDef declaringType2; - - /// - public ModuleDef Module => declaringType2?.Module; - - /// - /// Gets the full name of the event - /// - public string FullName => FullNameFactory.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 - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, EventAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((EventAttributes)attributes & EventAttributes.SpecialName) != 0; - set => ModifyAttributes(value, EventAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((EventAttributes)attributes & EventAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, EventAttributes.RTSpecialName); - } - - /// - public override string ToString() => FullName; - } - - /// - /// An Event row created by the user and not present in the original .NET file - /// - public class EventDefUser : EventDef { - /// - /// Default constructor - /// - public EventDefUser() { - } - - /// - /// Constructor - /// - /// Name - public EventDefUser(UTF8String name) - : this(name, null, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Type - public EventDefUser(UTF8String name, ITypeDefOrRef type) - : this(name, type, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Type - /// Flags - public EventDefUser(UTF8String name, ITypeDefOrRef type, EventAttributes flags) { - this.name = name; - eventType = type; - attributes = (int)flags; - } - } - - /// - /// Created from a row in the Event table - /// - sealed class EventDefMD : EventDef, 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.Event, 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(declaringType2), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this Event row - /// Row ID - /// If is null - /// If is invalid - public EventDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.EventTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Event rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadEventRow(origRid, out var row); - Debug.Assert(b); - attributes = row.EventFlags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - declaringType2 = readerModule.GetOwnerType(this); - eventType = readerModule.ResolveTypeDefOrRef(row.EventType, new GenericParamContext(declaringType2)); - } - - internal EventDefMD InitializeAll() { - MemberMDInitializer.Initialize(Attributes); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(EventType); - MemberMDInitializer.Initialize(CustomAttributes); - MemberMDInitializer.Initialize(AddMethod); - MemberMDInitializer.Initialize(InvokeMethod); - MemberMDInitializer.Initialize(RemoveMethod); - MemberMDInitializer.Initialize(OtherMethods); - MemberMDInitializer.Initialize(DeclaringType); - return this; - } - - /// - protected override void InitializeEventMethods_NoLock() { - IList newOtherMethods; - var dt = declaringType2 as TypeDefMD; - if (dt is null) - newOtherMethods = new List(); - else - dt.InitializeEvent(this, out addMethod, out invokeMethod, out removeMethod, out newOtherMethods); - otherMethods = newOtherMethods; - } - } -} diff --git a/Plugins/dnlib/DotNet/ExportedType.cs b/Plugins/dnlib/DotNet/ExportedType.cs deleted file mode 100644 index 270f556..0000000 --- a/Plugins/dnlib/DotNet/ExportedType.cs +++ /dev/null @@ -1,690 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the ExportedType table - /// - public abstract class ExportedType : IHasCustomAttribute, IImplementation, IHasCustomDebugInformation, IType { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// The owner module - /// - protected ModuleDef module; - - /// - public MDToken MDToken => new MDToken(Table.ExportedType, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 17; - - /// - public int ImplementationTag => 2; - - /// - /// 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 => 17; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 IsValueType { - get { - var td = Resolve(); - return td is not null && td.IsValueType; - } - } - - /// - public bool IsPrimitive => this.IsPrimitive(); - - /// - string IType.TypeName => TypeName; - - /// - public UTF8String Name { - get => typeName; - set => typeName = value; - } - - /// - public string ReflectionName => FullNameFactory.Name(this, true, null); - - /// - public string Namespace => TypeNamespace; - - /// - public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); - - /// - public string FullName => FullNameFactory.FullName(this, false, null, null); - - /// - public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); - - /// - public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); - - /// - public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); - - /// - public IScope Scope => FullNameFactory.Scope(this); - - /// - public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); - - /// - /// Always returns false since a does not contain any - /// or . - /// - public bool ContainsGenericParameter => false; - - /// - public ModuleDef Module => module; - - /// - bool IIsTypeOrMethod.IsMethod => false; - - /// - bool IIsTypeOrMethod.IsType => true; - - /// - int IGenericParameterProvider.NumberOfGenericParameters => 0; - - /// - /// From column ExportedType.Flags - /// - public TypeAttributes Attributes { - get => (TypeAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column ExportedType.TypeDefId - /// - public uint TypeDefId { - get => typeDefId; - set => typeDefId = value; - } - /// - protected uint typeDefId; - - /// - /// From column ExportedType.TypeName - /// - public UTF8String TypeName { - get => typeName; - set => typeName = value; - } - /// - protected UTF8String typeName; - - /// - /// From column ExportedType.TypeNamespace - /// - public UTF8String TypeNamespace { - get => typeNamespace; - set => typeNamespace = value; - } - /// - protected UTF8String typeNamespace; - - /// - /// From column ExportedType.Implementation - /// - public IImplementation Implementation { - get { - if (!implementation_isInitialized) - InitializeImplementation(); - return implementation; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - implementation = value; - implementation_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected IImplementation implementation; - /// - protected bool implementation_isInitialized; - - void InitializeImplementation() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (implementation_isInitialized) - return; - implementation = GetImplementation_NoLock(); - implementation_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual IImplementation GetImplementation_NoLock() => null; - - /// - /// true if it's nested within another - /// - public bool IsNested => DeclaringType is not null; - - /// - /// Gets the declaring type, if any - /// - public ExportedType DeclaringType { - get { - if (!implementation_isInitialized) - InitializeImplementation(); - return implementation as ExportedType; - } - } - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(TypeAttributes andMask, TypeAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, TypeAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the visibility - /// - public TypeAttributes Visibility { - get => (TypeAttributes)attributes & TypeAttributes.VisibilityMask; - set => ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); - } - - /// - /// true if is set - /// - public bool IsNotPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; - - /// - /// true if is set - /// - public bool IsPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; - - /// - /// true if is set - /// - public bool IsNestedPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; - - /// - /// true if is set - /// - public bool IsNestedPrivate => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; - - /// - /// true if is set - /// - public bool IsNestedFamily => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; - - /// - /// true if is set - /// - public bool IsNestedAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; - - /// - /// true if is set - /// - public bool IsNestedFamilyAndAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; - - /// - /// true if is set - /// - public bool IsNestedFamilyOrAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; - - /// - /// Gets/sets the layout - /// - public TypeAttributes Layout { - get => (TypeAttributes)attributes & TypeAttributes.LayoutMask; - set => ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); - } - - /// - /// true if is set - /// - public bool IsAutoLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; - - /// - /// true if is set - /// - public bool IsSequentialLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; - - /// - /// true if is set - /// - public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; - - /// - /// Gets/sets the bit - /// - public bool IsInterface { - get => ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; - set => ModifyAttributes(value, TypeAttributes.Interface); - } - - /// - /// Gets/sets the bit - /// - public bool IsClass { - get => ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; - set => ModifyAttributes(!value, TypeAttributes.Interface); - } - - /// - /// Gets/sets the bit - /// - public bool IsAbstract { - get => ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; - set => ModifyAttributes(value, TypeAttributes.Abstract); - } - - /// - /// Gets/sets the bit - /// - public bool IsSealed { - get => ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; - set => ModifyAttributes(value, TypeAttributes.Sealed); - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; - set => ModifyAttributes(value, TypeAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsImport { - get => ((TypeAttributes)attributes & TypeAttributes.Import) != 0; - set => ModifyAttributes(value, TypeAttributes.Import); - } - - /// - /// Gets/sets the bit - /// - public bool IsSerializable { - get => ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; - set => ModifyAttributes(value, TypeAttributes.Serializable); - } - - /// - /// Gets/sets the bit - /// - public bool IsWindowsRuntime { - get => ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; - set => ModifyAttributes(value, TypeAttributes.WindowsRuntime); - } - - /// - /// Gets/sets the string format - /// - public TypeAttributes StringFormat { - get => (TypeAttributes)attributes & TypeAttributes.StringFormatMask; - set => ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); - } - - /// - /// true if is set - /// - public bool IsAnsiClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; - - /// - /// true if is set - /// - public bool IsUnicodeClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; - - /// - /// true if is set - /// - public bool IsAutoClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; - - /// - /// true if is set - /// - public bool IsCustomFormatClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; - - /// - /// Gets/sets the bit - /// - public bool IsBeforeFieldInit { - get => ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; - set => ModifyAttributes(value, TypeAttributes.BeforeFieldInit); - } - - /// - /// Gets/sets the bit. See also - /// - public bool IsForwarder { - get => ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; - set => ModifyAttributes(value, TypeAttributes.Forwarder); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, TypeAttributes.RTSpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool HasSecurity { - get => ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; - set => ModifyAttributes(value, TypeAttributes.HasSecurity); - } - - const int MAX_LOOP_ITERS = 50; - - /// - /// true if this type has been moved to another assembly - /// - public bool MovedToAnotherAssembly { - get { - var et = this; - for (int i = 0; i < MAX_LOOP_ITERS; i++) { - var impl = et.Implementation; - if (impl is AssemblyRef) - return et.IsForwarder; - - et = impl as ExportedType; - if (et is null) - break; - } - return false; - } - } - - /// - /// Resolves the type - /// - /// A instance or null if it couldn't be resolved - public TypeDef Resolve() => Resolve(null); - - /// - /// Resolves the type - /// - /// Source module or null - /// A instance or null if it couldn't be resolved - public TypeDef Resolve(ModuleDef sourceModule) { - if (module is null) - return null; - - return Resolve(sourceModule, this); - } - - static TypeDef Resolve(ModuleDef sourceModule, ExportedType et) { - for (int i = 0; i < MAX_LOOP_ITERS; i++) { - 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 is null) - break; - - var td = etAsm.Find(et.FullName, false); - if (td is not null) - return td; - - et = FindExportedType(etAsm, et); - } - - return null; - } - - static ExportedType FindExportedType(AssemblyDef asm, ExportedType et) { - 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; - } - } - return null; - } - - /// - /// Resolves the type - /// - /// A instance - /// If the type couldn't be resolved - public TypeDef ResolveThrow() { - var type = Resolve(); - if (type is not null) - return type; - throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); - } - - /// - /// Converts this instance to a - /// - /// A new instance - public TypeRef ToTypeRef() { - TypeRef result = null, prev = null; - var mod = module; - IImplementation impl = this; - 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 not null) - prev.ResolutionScope = newTr; - - prev = newTr; - impl = et.Implementation; - continue; - } - - if (impl is AssemblyRef asmRef) { - // prev is never null when we're here - prev.ResolutionScope = asmRef; - return result; - } - - if (impl is FileDef file) { - // prev is never null when we're here - prev.ResolutionScope = FindModule(mod, file); - return result; - } - - break; - } - return result; - } - - static ModuleDef FindModule(ModuleDef module, FileDef file) { - if (module is null || file is null) - return null; - if (UTF8String.CaseInsensitiveEquals(module.Name, file.Name)) - return module; - var asm = module.Assembly; - if (asm is null) - return null; - return asm.FindModule(file.Name); - } - - /// - public override string ToString() => FullName; - } - - /// - /// An ExportedType row created by the user and not present in the original .NET file - /// - public class ExportedTypeUser : ExportedType { - /// - /// Constructor - /// - /// Owner module - public ExportedTypeUser(ModuleDef module) => this.module = module; - - /// - /// Constructor - /// - /// Owner module - /// TypeDef ID - /// Type name - /// Type namespace - /// Flags - /// Implementation - public ExportedTypeUser(ModuleDef module, uint typeDefId, UTF8String typeNamespace, UTF8String typeName, TypeAttributes flags, IImplementation implementation) { - this.module = module; - this.typeDefId = typeDefId; - this.typeName = typeName; - this.typeNamespace = typeNamespace; - attributes = (int)flags; - this.implementation = implementation; - implementation_isInitialized = true; - } - } - - /// - /// Created from a row in the ExportedType table - /// - sealed class ExportedTypeMD : ExportedType, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly uint implementationRid; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.ExportedType, 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); - } - - /// - protected override IImplementation GetImplementation_NoLock() => - readerModule.ResolveImplementation(implementationRid); - - /// - /// Constructor - /// - /// The module which contains this ExportedType row - /// Row ID - /// If is null - /// If is invalid - public ExportedTypeMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ExportedTypeTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"ExportedType rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - module = readerModule; - bool b = readerModule.TablesStream.TryReadExportedTypeRow(origRid, out var row); - implementationRid = row.Implementation; - attributes = (int)row.Flags; - typeDefId = row.TypeDefId; - typeName = readerModule.StringsStream.ReadNoNull(row.TypeName); - typeNamespace = readerModule.StringsStream.ReadNoNull(row.TypeNamespace); - } - } -} diff --git a/Plugins/dnlib/DotNet/Extensions.cs b/Plugins/dnlib/DotNet/Extensions.cs deleted file mode 100644 index 2d5da47..0000000 --- a/Plugins/dnlib/DotNet/Extensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Extension methods - /// - public static partial class Extensions { - } -} diff --git a/Plugins/dnlib/DotNet/FieldAttributes.cs b/Plugins/dnlib/DotNet/FieldAttributes.cs deleted file mode 100644 index 137beed..0000000 --- a/Plugins/dnlib/DotNet/FieldAttributes.cs +++ /dev/null @@ -1,54 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Field flags, see CorHdr.h/CorFieldAttr - /// - [Flags] - public enum FieldAttributes : ushort { - /// member access mask - Use this mask to retrieve accessibility information. - FieldAccessMask = 0x0007, - /// Member not referenceable. - PrivateScope = 0x0000, - /// Member not referenceable. - CompilerControlled = PrivateScope, - /// Accessible only by the parent type. - Private = 0x0001, - /// Accessible by sub-types only in this Assembly. - FamANDAssem = 0x0002, - /// Accessibly by anyone in the Assembly. - Assembly = 0x0003, - /// Accessible only by type and sub-types. - Family = 0x0004, - /// Accessibly by sub-types anywhere, plus anyone in assembly. - FamORAssem = 0x0005, - /// Accessibly by anyone who has visibility to this scope. - Public = 0x0006, - - /// Defined on type, else per instance. - Static = 0x0010, - /// Field may only be initialized, not written to after init. - InitOnly = 0x0020, - /// Value is compile time constant. - Literal = 0x0040, - /// Field does not have to be serialized when type is remoted. - NotSerialized = 0x0080, - - /// field is special. Name describes how. - SpecialName = 0x0200, - - /// Implementation is forwarded through pinvoke. - PinvokeImpl = 0x2000, - - /// Runtime(metadata internal APIs) should check name encoding. - RTSpecialName = 0x0400, - /// Field has marshalling information. - HasFieldMarshal = 0x1000, - /// Field has default. - HasDefault = 0x8000, - /// Field has RVA. - HasFieldRVA = 0x0100, - } -} diff --git a/Plugins/dnlib/DotNet/FieldDef.cs b/Plugins/dnlib/DotNet/FieldDef.cs deleted file mode 100644 index 1e72ac3..0000000 --- a/Plugins/dnlib/DotNet/FieldDef.cs +++ /dev/null @@ -1,864 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.PE; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Field table - /// - public abstract class FieldDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal, IMemberForwarded, IHasCustomDebugInformation, IField, ITokenOperand, IMemberDef { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.Field, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasConstantTag => 0; - - /// - public int HasCustomAttributeTag => 1; - - /// - public int HasFieldMarshalTag => 0; - - /// - public int MemberForwardedTag => 0; - - /// - /// 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 int HasCustomDebugInformationTag => 1; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// From column Field.Flags - /// - public FieldAttributes Attributes { - get => (FieldAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column Field.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column Field.Signature - /// - public CallingConventionSig Signature { - get => signature; - set => signature = value; - } - /// - protected CallingConventionSig signature; - - /// - /// Gets/sets the field layout offset - /// - public uint? FieldOffset { - get { - if (!fieldOffset_isInitialized) - InitializeFieldOffset(); - return fieldOffset; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - fieldOffset = value; - fieldOffset_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected uint? fieldOffset; - /// - protected bool fieldOffset_isInitialized; - - void InitializeFieldOffset() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (fieldOffset_isInitialized) - return; - fieldOffset = GetFieldOffset_NoLock(); - fieldOffset_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual uint? GetFieldOffset_NoLock() => null; - - /// - public MarshalType MarshalType { - get { - if (!marshalType_isInitialized) - InitializeMarshalType(); - return marshalType; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - marshalType = value; - marshalType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected MarshalType marshalType; - /// - protected bool marshalType_isInitialized; - - void InitializeMarshalType() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (marshalType_isInitialized) - return; - marshalType = GetMarshalType_NoLock(); - marshalType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual MarshalType GetMarshalType_NoLock() => null; - - /// Reset - protected void ResetMarshalType() => - marshalType_isInitialized = false; - - /// - /// Gets/sets the field RVA - /// - public RVA RVA { - get { - if (!rva_isInitialized) - InitializeRVA(); - return rva; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - rva = value; - rva_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected RVA rva; - /// - protected bool rva_isInitialized; - - void InitializeRVA() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (rva_isInitialized) - return; - rva = GetRVA_NoLock(); - rva_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual RVA GetRVA_NoLock() => 0; - - /// Reset - protected void ResetRVA() => rva_isInitialized = false; - - /// - /// Gets/sets the initial value. Be sure to set to true if - /// you write to this field. - /// - public byte[] InitialValue { - get { - if (!initialValue_isInitialized) - InitializeInitialValue(); - return initialValue; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - initialValue = value; - initialValue_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected byte[] initialValue; - /// - protected bool initialValue_isInitialized; - - void InitializeInitialValue() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (initialValue_isInitialized) - return; - initialValue = GetInitialValue_NoLock(); - initialValue_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual byte[] GetInitialValue_NoLock() => null; - - /// Reset - protected void ResetInitialValue() => initialValue_isInitialized = false; - - /// - public ImplMap ImplMap { - get { - if (!implMap_isInitialized) - InitializeImplMap(); - return implMap; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - implMap = value; - implMap_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected ImplMap implMap; - /// - protected bool implMap_isInitialized; - - void InitializeImplMap() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (implMap_isInitialized) - return; - implMap = GetImplMap_NoLock(); - implMap_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual ImplMap GetImplMap_NoLock() => null; - - /// - public Constant Constant { - get { - if (!constant_isInitialized) - InitializeConstant(); - return constant; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - constant = value; - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected Constant constant; - /// - protected bool constant_isInitialized; - - void InitializeConstant() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (constant_isInitialized) - return; - constant = GetConstant_NoLock(); - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual Constant GetConstant_NoLock() => null; - - /// Reset - protected void ResetConstant() => constant_isInitialized = false; - - /// - public bool HasCustomAttributes => CustomAttributes.Count > 0; - - /// - public bool HasImplMap => ImplMap is not null; - - /// - /// Gets/sets the declaring type (owner type) - /// - public TypeDef DeclaringType { - get => declaringType2; - set { - var currentDeclaringType = DeclaringType2; - if (currentDeclaringType == value) - return; - if (currentDeclaringType is not null) - currentDeclaringType.Fields.Remove(this); // Will set DeclaringType2 = null - if (value is not null) - value.Fields.Add(this); // Will set DeclaringType2 = value - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; - - /// - /// Called by and should normally not be called by any user - /// code. Use instead. Only call this if you must set the - /// declaring type without inserting it in the declaring type's method list. - /// - public TypeDef DeclaringType2 { - get => declaringType2; - set => declaringType2 = value; - } - /// - protected TypeDef declaringType2; - - /// - /// Gets/sets the - /// - public FieldSig FieldSig { - get => signature as FieldSig; - set => signature = value; - } - - /// - 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 => FieldOffset is not null; - - /// - /// true if is not null - /// - public bool HasConstant => Constant is not null; - - /// - /// Gets the constant element type or if there's no constant - /// - public ElementType ElementType { - get { - var c = Constant; - return c is null ? ElementType.End : c.Type; - } - } - - /// - /// true if is not null - /// - public bool HasMarshalType => MarshalType is not null; - - /// - /// Gets/sets the field type - /// - public TypeSig FieldType { - get => FieldSig.GetFieldType(); - set { - var sig = FieldSig; - if (sig is not null) - sig.Type = value; - } - } - - /// - /// Modify field: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(FieldAttributes andMask, FieldAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, FieldAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the field access - /// - public FieldAttributes Access { - get => (FieldAttributes)attributes & FieldAttributes.FieldAccessMask; - set => ModifyAttributes(~FieldAttributes.FieldAccessMask, value & FieldAttributes.FieldAccessMask); - } - - /// - /// true if is set - /// - public bool IsCompilerControlled => IsPrivateScope; - - /// - /// true if is set - /// - public bool IsPrivateScope => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.PrivateScope; - - /// - /// true if is set - /// - public bool IsPrivate => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Private; - - /// - /// true if is set - /// - public bool IsFamilyAndAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamANDAssem; - - /// - /// true if is set - /// - public bool IsAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Assembly; - - /// - /// true if is set - /// - public bool IsFamily => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Family; - - /// - /// true if is set - /// - public bool IsFamilyOrAssembly => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.FamORAssem; - - /// - /// true if is set - /// - public bool IsPublic => ((FieldAttributes)attributes & FieldAttributes.FieldAccessMask) == FieldAttributes.Public; - - /// - /// Gets/sets the bit - /// - public bool IsStatic { - get => ((FieldAttributes)attributes & FieldAttributes.Static) != 0; - set => ModifyAttributes(value, FieldAttributes.Static); - } - - /// - /// Gets/sets the bit - /// - public bool IsInitOnly { - get => ((FieldAttributes)attributes & FieldAttributes.InitOnly) != 0; - set => ModifyAttributes(value, FieldAttributes.InitOnly); - } - - /// - /// Gets/sets the bit - /// - public bool IsLiteral { - get => ((FieldAttributes)attributes & FieldAttributes.Literal) != 0; - set => ModifyAttributes(value, FieldAttributes.Literal); - } - - /// - /// Gets/sets the bit - /// - public bool IsNotSerialized { - get => ((FieldAttributes)attributes & FieldAttributes.NotSerialized) != 0; - set => ModifyAttributes(value, FieldAttributes.NotSerialized); - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((FieldAttributes)attributes & FieldAttributes.SpecialName) != 0; - set => ModifyAttributes(value, FieldAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsPinvokeImpl { - get => ((FieldAttributes)attributes & FieldAttributes.PinvokeImpl) != 0; - set => ModifyAttributes(value, FieldAttributes.PinvokeImpl); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((FieldAttributes)attributes & FieldAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, FieldAttributes.RTSpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool HasFieldMarshal { - get => ((FieldAttributes)attributes & FieldAttributes.HasFieldMarshal) != 0; - set => ModifyAttributes(value, FieldAttributes.HasFieldMarshal); - } - - /// - /// Gets/sets the bit - /// - public bool HasDefault { - get => ((FieldAttributes)attributes & FieldAttributes.HasDefault) != 0; - set => ModifyAttributes(value, FieldAttributes.HasDefault); - } - - /// - /// Gets/sets the bit - /// - public bool HasFieldRVA { - get => ((FieldAttributes)attributes & FieldAttributes.HasFieldRVA) != 0; - set => ModifyAttributes(value, FieldAttributes.HasFieldRVA); - } - - /// - /// Returns the full name of this field - /// - public string FullName => FullNameFactory.FieldFullName(declaringType2?.FullName, name, FieldSig, null, null); - - /// - /// Gets the size of this field in bytes or 0 if unknown. - /// - public uint GetFieldSize() { - if (!GetFieldSize(out uint size)) - return 0; - return size; - } - - /// - /// Gets the size of this field in bytes or 0 if unknown. - /// - /// Updated with size - /// true if is valid, false otherwise - public bool GetFieldSize(out uint size) => GetFieldSize(declaringType2, FieldSig, out size); - - /// - /// Gets the size of this field in bytes or 0 if unknown. - /// - /// The declaring type of this - /// The field signature of this - /// Updated with size - /// true if is valid, false otherwise - 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. - /// - /// The declaring type of this - /// The field signature of this - /// Size of a pointer - /// Updated with size - /// true if is valid, false otherwise - protected bool GetFieldSize(TypeDef declaringType, FieldSig fieldSig, int ptrSize, out uint size) { - size = 0; - if (fieldSig is null) - return false; - return GetClassSize(declaringType, fieldSig.Type, ptrSize, out size); - } - - bool GetClassSize(TypeDef declaringType, TypeSig ts, int ptrSize, out uint size) { - size = 0; - ts = ts.RemovePinnedAndModifiers(); - if (ts is null) - return false; - - int size2 = ts.ElementType.GetPrimitiveSize(ptrSize); - if (size2 >= 0) { - size = (uint)size2; - return true; - } - - var tdrs = ts as TypeDefOrRefSig; - if (tdrs is null) - return false; - - var td = tdrs.TypeDef; - if (td is not null) - return TypeDef.GetClassSize(td, out size); - - var tr = tdrs.TypeRef; - if (tr is not null) - return TypeDef.GetClassSize(tr.Resolve(), out size); - - return false; - } - - int GetPointerSize(TypeDef declaringType) { - if (declaringType is null) - return 4; - var module = declaringType.Module; - if (module is null) - return 4; - return module.GetPointerSize(); - } - - /// - public override string ToString() => FullName; - } - - /// - /// A Field row created by the user and not present in the original .NET file - /// - public class FieldDefUser : FieldDef { - /// - /// Default constructor - /// - public FieldDefUser() { - } - - /// - /// Constructor - /// - /// Name - public FieldDefUser(UTF8String name) - : this(name, null) { - } - - /// - /// Constructor - /// - /// Name - /// Signature - public FieldDefUser(UTF8String name, FieldSig signature) - : this(name, signature, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Signature - /// Flags - public FieldDefUser(UTF8String name, FieldSig signature, FieldAttributes attributes) { - this.name = name; - this.signature = signature; - this.attributes = (int)attributes; - } - } - - /// - /// Created from a row in the Field table - /// - sealed class FieldDefMD : FieldDef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly FieldAttributes origAttributes; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.Field, 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(declaringType2), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - protected override uint? GetFieldOffset_NoLock() { - if (readerModule.TablesStream.TryReadFieldLayoutRow(readerModule.Metadata.GetFieldLayoutRid(origRid), out var row)) - return row.OffSet; - return null; - } - - /// - protected override MarshalType GetMarshalType_NoLock() => - readerModule.ReadMarshalType(Table.Field, origRid, new GenericParamContext(declaringType2)); - - /// - protected override RVA GetRVA_NoLock() { - GetFieldRVA_NoLock(out var rva2); - return rva2; - } - - /// - protected override byte[] GetInitialValue_NoLock() { - if (!GetFieldRVA_NoLock(out var rva2)) - return null; - return ReadInitialValue_NoLock(rva2); - } - - /// - protected override ImplMap GetImplMap_NoLock() => - readerModule.ResolveImplMap(readerModule.Metadata.GetImplMapRid(Table.Field, origRid)); - - /// - protected override Constant GetConstant_NoLock() => - readerModule.ResolveConstant(readerModule.Metadata.GetConstantRid(Table.Field, origRid)); - - /// - /// Constructor - /// - /// The module which contains this Field row - /// Row ID - /// If is null - /// If is invalid - public FieldDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.FieldTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Field rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadFieldRow(origRid, out var row); - Debug.Assert(b); - name = readerModule.StringsStream.ReadNoNull(row.Name); - attributes = row.Flags; - origAttributes = (FieldAttributes)attributes; - declaringType2 = readerModule.GetOwnerType(this); - signature = readerModule.ReadSignature(row.Signature, new GenericParamContext(declaringType2)); - } - - internal FieldDefMD InitializeAll() { - MemberMDInitializer.Initialize(CustomAttributes); - MemberMDInitializer.Initialize(Attributes); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(Signature); - MemberMDInitializer.Initialize(FieldOffset); - MemberMDInitializer.Initialize(MarshalType); - MemberMDInitializer.Initialize(RVA); - MemberMDInitializer.Initialize(InitialValue); - MemberMDInitializer.Initialize(ImplMap); - MemberMDInitializer.Initialize(Constant); - MemberMDInitializer.Initialize(DeclaringType); - return this; - } - - bool GetFieldRVA_NoLock(out RVA rva) { - if ((origAttributes & FieldAttributes.HasFieldRVA) == 0) { - rva = 0; - return false; - } - if (!readerModule.TablesStream.TryReadFieldRVARow(readerModule.Metadata.GetFieldRVARid(origRid), out var row)) { - rva = 0; - return false; - } - rva = (RVA)row.RVA; - return true; - } - - byte[] ReadInitialValue_NoLock(RVA rva) { - if (!GetFieldSize(declaringType2, signature as FieldSig, out uint size)) - return null; - if (size >= int.MaxValue) - return null; - return readerModule.ReadDataAt(rva, (int)size); - } - } -} diff --git a/Plugins/dnlib/DotNet/FileAttributes.cs b/Plugins/dnlib/DotNet/FileAttributes.cs deleted file mode 100644 index 3fab691..0000000 --- a/Plugins/dnlib/DotNet/FileAttributes.cs +++ /dev/null @@ -1,16 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// File row flags. See CorHdr.h/CorFileFlags - /// - [Flags] - public enum FileAttributes : uint { - /// This is not a resource file - ContainsMetadata = 0x0000, - /// This is a resource file or other non-metadata-containing file - ContainsNoMetadata = 0x0001, - } -} diff --git a/Plugins/dnlib/DotNet/FileDef.cs b/Plugins/dnlib/DotNet/FileDef.cs deleted file mode 100644 index 9f65542..0000000 --- a/Plugins/dnlib/DotNet/FileDef.cs +++ /dev/null @@ -1,215 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the File table - /// - public abstract class FileDef : IHasCustomAttribute, IImplementation, IHasCustomDebugInformation, IManagedEntryPoint { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.File, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 16; - - /// - public int ImplementationTag => 0; - - /// - /// From column File.Flags - /// - public FileAttributes Flags { - get => (FileAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column File.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column File.HashValue - /// - public byte[] HashValue { - get => hashValue; - set => hashValue = value; - } - /// - protected byte[] hashValue; - - /// - /// 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 => 16; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, FileAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool ContainsMetadata { - get => ((FileAttributes)attributes & FileAttributes.ContainsNoMetadata) == 0; - set => ModifyAttributes(!value, FileAttributes.ContainsNoMetadata); - } - - /// - /// Gets/sets the bit - /// - public bool ContainsNoMetadata { - get => ((FileAttributes)attributes & FileAttributes.ContainsNoMetadata) != 0; - set => ModifyAttributes(value, FileAttributes.ContainsNoMetadata); - } - - /// - public string FullName => UTF8String.ToSystemStringOrEmpty(name); - - /// - public override string ToString() => FullName; - } - - /// - /// A File row created by the user and not present in the original .NET file - /// - public class FileDefUser : FileDef { - /// - /// Default constructor - /// - public FileDefUser() { - } - - /// - /// Constructor - /// - /// Name of file - /// Flags - /// File hash - public FileDefUser(UTF8String name, FileAttributes flags, byte[] hashValue) { - this.name = name; - attributes = (int)flags; - this.hashValue = hashValue; - } - } - - /// - /// Created from a row in the File table - /// - sealed class FileDefMD : FileDef, 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.File, 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); - } - - /// - /// Constructor - /// - /// The module which contains this File row - /// Row ID - /// If is null - /// If is invalid - public FileDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.FileTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"File rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadFileRow(origRid, out var row); - Debug.Assert(b); - attributes = (int)row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - hashValue = readerModule.BlobStream.Read(row.HashValue); - } - } -} diff --git a/Plugins/dnlib/DotNet/FrameworkRedirect.cs b/Plugins/dnlib/DotNet/FrameworkRedirect.cs deleted file mode 100644 index 7208342..0000000 --- a/Plugins/dnlib/DotNet/FrameworkRedirect.cs +++ /dev/null @@ -1,389 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Redirects .NET framework assembly references from older to newer versions - /// - public static class FrameworkRedirect { - static readonly Dictionary frmRedir2; - static readonly Dictionary frmRedir4; - - readonly struct FrameworkRedirectInfo { - public readonly PublicKeyToken publicKeyToken; - public readonly Version redirectVersion; - - public FrameworkRedirectInfo(string publicKeyToken, string redirectVersion) { - this.publicKeyToken = new PublicKeyToken(publicKeyToken); - this.redirectVersion = new Version(redirectVersion); - } - } - - static FrameworkRedirect() { - frmRedir2 = new Dictionary(StringComparer.OrdinalIgnoreCase); - frmRedir4 = new Dictionary(StringComparer.OrdinalIgnoreCase); - InitFrameworkRedirectV2(); - InitFrameworkRedirectV4(); - } - - static void InitFrameworkRedirectV2() { - frmRedir2["Accessibility"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["cscompmgd"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["CustomMarshalers"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["IEExecRemote"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["IEHost"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["IIEHost"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["ISymWrapper"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["Microsoft.JScript"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.VisualBasic"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.VisualBasic.Compatibility"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.VisualBasic.Compatibility.Data"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.VisualBasic.Vsa"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.VisualC"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.Vsa"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft.Vsa.Vb.CodeDOMProcessor"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["Microsoft_VsaVb"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "8.0.0.0"); - frmRedir2["mscorcfg"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["mscorlib"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Configuration"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Configuration.Install"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Data"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Data.OracleClient"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Data.SqlXml"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Deployment"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Design"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.DirectoryServices"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.DirectoryServices.Protocols"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Drawing"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Drawing.Design"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.EnterpriseServices"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Management"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Messaging"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Runtime.Remoting"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Runtime.Serialization.Formatters.Soap"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Security"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.ServiceProcess"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Transactions"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Web"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Web.Mobile"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Web.RegularExpressions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Web.Services"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["System.Windows.Forms"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["System.Xml"] = new FrameworkRedirectInfo("b77a5c561934e089", "2.0.0.0"); - frmRedir2["vjscor"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["VJSharpCodeProvider"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjsJBC"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjslib"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjslibcw"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["Vjssupuilib"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjsvwaux"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjswfc"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["VJSWfcBrowserStubLib"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjswfccw"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir2["vjswfchtml"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - } - - static void InitFrameworkRedirectV4() { - frmRedir4["Accessibility"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["CustomMarshalers"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["ISymWrapper"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.JScript"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["Microsoft.VisualBasic"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["Microsoft.VisualBasic.Compatibility"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["Microsoft.VisualBasic.Compatibility.Data"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["Microsoft.VisualC"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["mscorlib"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Configuration"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Configuration.Install"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Data"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.OracleClient"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.SqlXml"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Deployment"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Design"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.DirectoryServices"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.DirectoryServices.Protocols"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Drawing"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Drawing.Design"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.EnterpriseServices"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Management"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Messaging"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Remoting"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Runtime.Serialization.Formatters.Soap"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Security"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceProcess"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Transactions"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Web"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Web.Mobile"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Web.RegularExpressions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Web.Services"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Windows.Forms"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Xml"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["AspNetMMCExt"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["sysglobl"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Build.Engine"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Build.Framework"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["PresentationCFFRasterizer"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationCore"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.Aero"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.Classic"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.Luna"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.Royale"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationUI"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["ReachFramework"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Printing"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Speech"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["UIAutomationClient"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["UIAutomationClientsideProviders"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["UIAutomationProvider"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["UIAutomationTypes"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["WindowsBase"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["WindowsFormsIntegration"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["SMDiagnostics"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IdentityModel"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IdentityModel.Selectors"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IO.Log"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Serialization"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.ServiceModel"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.ServiceModel.Install"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.ServiceModel.WasHosting"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Workflow.Activities"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Workflow.ComponentModel"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Workflow.Runtime"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["Microsoft.Transactions.Bridge"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Transactions.Bridge.Dtc"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.AddIn"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.AddIn.Contract"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ComponentModel.Composition"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Core"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.DataSetExtensions"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.Linq"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Xml.Linq"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.DirectoryServices.AccountManagement"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Management.Instrumentation"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Net"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.Web"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.Extensions"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.Extensions.Design"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Windows.Presentation"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.WorkflowServices"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ComponentModel.DataAnnotations"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Data.Entity"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.Entity.Design"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.Services"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.Services.Client"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Data.Services.Design"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Web.Abstractions"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.DynamicData"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.DynamicData.Design"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.Entity"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Web.Entity.Design"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Web.Routing"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["Microsoft.Build"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.CSharp"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Dynamic"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Numerics"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Xaml"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["Microsoft.Workflow.Compiler"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["Microsoft.Activities.Build"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["Microsoft.Build.Conversion.v4.0"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Build.Tasks.v4.0"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Build.Utilities.v4.0"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["Microsoft.Internal.Tasks.Dataflow"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["Microsoft.VisualBasic.Activities.Compiler"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "10.0.0.0"); - frmRedir4["Microsoft.VisualC.STLCLR"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "2.0.0.0"); - frmRedir4["Microsoft.Windows.ApplicationServer.Applications"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationBuildTasks"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.Aero2"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework.AeroLite"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["PresentationFramework-SystemCore"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["PresentationFramework-SystemData"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["PresentationFramework-SystemDrawing"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["PresentationFramework-SystemXml"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["PresentationFramework-SystemXmlLinq"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Activities"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Activities.Core.Presentation"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Activities.DurableInstancing"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Activities.Presentation"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ComponentModel.Composition.Registration"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Device"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IdentityModel.Services"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IO.Compression"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.IO.Compression.FileSystem"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Net.Http"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Net.Http.WebRequest"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Context"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Runtime.Caching"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.DurableInstancing"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Runtime.WindowsRuntime"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Runtime.WindowsRuntime.UI.Xaml"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.ServiceModel.Activation"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.Activities"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.Channels"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.Discovery"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.Internals"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.Routing"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.ServiceModel.ServiceMoniker40"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Web.ApplicationServices"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.DataVisualization"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Web.DataVisualization.Design"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Windows.Controls.Ribbon"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Windows.Forms.DataVisualization"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Windows.Forms.DataVisualization.Design"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Windows.Input.Manipulations"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - frmRedir4["System.Xaml.Hosting"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["XamlBuildTask"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["XsdBuildTask"] = new FrameworkRedirectInfo("31bf3856ad364e35", "4.0.0.0"); - frmRedir4["System.Collections"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Collections.Concurrent"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ComponentModel"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ComponentModel.Annotations"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ComponentModel.EventBasedAsync"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Diagnostics.Contracts"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Diagnostics.Debug"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Diagnostics.Tools"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Diagnostics.Tracing"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Dynamic.Runtime"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Globalization"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.IO"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Linq"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Linq.Expressions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Linq.Parallel"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Linq.Queryable"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Net.NetworkInformation"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Net.Primitives"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Net.Requests"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ObjectModel"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Emit"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Emit.ILGeneration"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Emit.Lightweight"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Extensions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Reflection.Primitives"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Resources.ResourceManager"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Extensions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.InteropServices"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.InteropServices.WindowsRuntime"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Numerics"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Serialization.Json"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Serialization.Primitives"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Runtime.Serialization.Xml"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Security.Principal"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.Duplex"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.Http"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.NetTcp"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.Primitives"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.ServiceModel.Security"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Text.Encoding"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Text.Encoding.Extensions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Text.RegularExpressions"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Threading"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Threading.Timer"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Threading.Tasks"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Threading.Tasks.Parallel"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Xml.ReaderWriter"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Xml.XDocument"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Xml.XmlSerializer"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Net.Http.Rtc"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Windows"] = new FrameworkRedirectInfo("b03f5f7f11d50a3a", "4.0.0.0"); - frmRedir4["System.Xml.Serialization"] = new FrameworkRedirectInfo("b77a5c561934e089", "4.0.0.0"); - } - - /// - /// Redirects a .NET Framework assembly from an older version to the correct version - /// loaded at runtime. - /// - /// Current assembly reference that might get updated - /// Module using the assembly reference - public static void ApplyFrameworkRedirect(ref IAssembly assembly, ModuleDef sourceModule) { - if (TryApplyFrameworkRedirectCore(assembly, sourceModule, out var redirectedAssembly)) - assembly = redirectedAssembly; - } - - /// - /// 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 is not null) { - if (sourceModule.IsClr40) - return TryApplyFrameworkRedirect(assembly, frmRedir4, out redirectedAssembly); - if (sourceModule.IsClr20) - return TryApplyFrameworkRedirect(assembly, frmRedir2, out redirectedAssembly); - } - - redirectedAssembly = null; - return false; - } - - /// - /// 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) { - 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) { - if (TryApplyFrameworkRedirect(assembly, frmRedir4, out var redirectedAssembly)) - assembly = redirectedAssembly; - } - - /// - /// 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 false; - if (PublicKeyBase.TokenCompareTo(assembly.PublicKeyOrToken, redirect.publicKeyToken) != 0) - return false; - - if (Utils.CompareTo(assembly.Version, redirect.redirectVersion) == 0) - redirectedAssembly = assembly; - else { - redirectedAssembly = new AssemblyNameInfo(assembly); - redirectedAssembly.Version = redirect.redirectVersion; - } - return true; - } - } -} diff --git a/Plugins/dnlib/DotNet/FullNameFactory.cs b/Plugins/dnlib/DotNet/FullNameFactory.cs deleted file mode 100644 index 5590bb7..0000000 --- a/Plugins/dnlib/DotNet/FullNameFactory.cs +++ /dev/null @@ -1,2246 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Text; - -namespace dnlib.DotNet { - /// - /// Helps create a name - /// - 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 - /// when the type already exists in the same module as the CA, or if the type - /// exists in mscorlib. - /// - /// The type (TypeDef, TypeRef or ExportedType) - /// or null - /// true if the assembly name must be included, false otherwise - bool MustUseAssemblyName(IType type); - } - - /// - /// Creates type names, method names, etc. - /// - public struct FullNameFactory { - const uint MaxArrayRank = 100; - const uint MaxMethodGenParamCount = 200; - const string RECURSION_ERROR_RESULT_STRING = "<<>>"; - const string NULLVALUE = "<<>>"; - readonly StringBuilder sb; - readonly bool isReflection; - readonly IFullNameFactoryHelper helper; - GenericArguments genericArguments; - RecursionCounter recursionCounter; - - /// - /// 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 - /// true if the assembly name must be included, false otherwise - 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; - - var tr = type as TypeRef; - if (tr is null) - return true; - if (tr.ResolutionScope == AssemblyRef.CurrentAssembly) - return false; - 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 not null; - } - else - return true; - } - - /// - /// 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, IFullNameFactoryHelper helper, StringBuilder sb) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - if (type is TypeDef td) - return FullNameSB(td, isReflection, helper, sb); - if (type is TypeRef tr) - return FullNameSB(tr, isReflection, helper, sb); - if (type is TypeSpec ts) - return FullNameSB(ts, isReflection, helper, sb); - if (type is TypeSig sig) - return FullNameSB(sig, isReflection, helper, null, null, sb); - if (type is ExportedType et) - 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) => - 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) { - if (type is TypeDef td) - return NameSB(td, isReflection, sb); - if (type is TypeRef tr) - return NameSB(tr, isReflection, sb); - if (type is TypeSpec ts) - return NameSB(ts, isReflection, sb); - if (type is TypeSig sig) - return NameSB(sig, isReflection, sb); - if (type is ExportedType et) - 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) => - 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) { - if (type is TypeDef td) - return NamespaceSB(td, isReflection, sb); - if (type is TypeRef tr) - return NamespaceSB(tr, isReflection, sb); - if (type is TypeSpec ts) - return NamespaceSB(ts, isReflection, sb); - if (type is TypeSig sig) - return NamespaceSB(sig, isReflection, sb); - if (type is ExportedType et) - return NamespaceSB(et, isReflection, sb); - return sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - if (type is TypeDef td) - return AssemblyQualifiedNameSB(td, helper, sb); - - if (type is TypeRef tr) - return AssemblyQualifiedNameSB(tr, helper, sb); - - if (type is TypeSpec ts) - return AssemblyQualifiedNameSB(ts, helper, sb); - - if (type is TypeSig sig) - return AssemblyQualifiedNameSB(sig, helper, sb); - - if (type is ExportedType et) - return AssemblyQualifiedNameSB(et, helper, sb); - - return sb ?? new StringBuilder(); - } - - /// - /// 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 = null, StringBuilder sb = null) => - 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 FullNameFactory(false, null, sb); - if (typeGenArgs is not null) { - fnc.genericArguments = new GenericArguments(); - fnc.genericArguments.PushTypeArgs(typeGenArgs); - } - - fnc.CreatePropertyFullName(declaringType, name, propertySig); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null, StringBuilder sb = null) => - 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 FullNameFactory(false, null, sb); - if (typeGenArgs is not null) { - fnc.genericArguments = new GenericArguments(); - fnc.genericArguments.PushTypeArgs(typeGenArgs); - } - - fnc.CreateEventFullName(declaringType, name, typeDefOrRef); - 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 - /// 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) => - 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 FullNameFactory(false, null, sb); - if (typeGenArgs is not null) { - fnc.genericArguments = new GenericArguments(); - fnc.genericArguments.PushTypeArgs(typeGenArgs); - } - - fnc.CreateFieldFullName(declaringType, name, fieldSig); - 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 - /// 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 = 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 - /// - /// 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 FullNameFactory(false, null, sb); - if (typeGenArgs is not null || methodGenArgs is not null) - fnc.genericArguments = new GenericArguments(); - if (typeGenArgs is not null) - fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (methodGenArgs is not null) - fnc.genericArguments.PushMethodArgs(methodGenArgs); - fnc.CreateMethodFullName(declaringType, name, methodSig, gppMethod); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null) => - 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 FullNameFactory(false, null, sb); - fnc.CreateMethodFullName(null, null, sig, null); - 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 - /// String builder to use or null - /// Sig full name - 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 - /// - /// 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 FullNameFactory(false, null, sb); - fnc.CreateMethodFullName(declType, name, sig, gppMethod); - return fnc.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 namespace - public static string Namespace(TypeRef typeRef, bool isReflection, StringBuilder sb = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeRef, true); - return fnc.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 name - public static string Name(TypeRef typeRef, bool isReflection, StringBuilder sb = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateName(typeRef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(isReflection, helper, sb); - fnc.CreateFullName(typeRef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(true, helper, sb); - fnc.CreateAssemblyQualifiedName(typeRef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// Returns the assembly where this type is defined - /// - /// The TypeRef - /// A or null if none found - public static IAssembly DefinitionAssembly(TypeRef typeRef) => - new FullNameFactory().GetDefinitionAssembly(typeRef); - - /// - /// Gets the scope - /// - /// The TypeRef - /// The or null if none found - public static IScope Scope(TypeRef typeRef) => - new FullNameFactory().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) => - new FullNameFactory().GetOwnerModule(typeRef); - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeDef, true); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateName(typeDef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(isReflection, helper, sb); - fnc.CreateFullName(typeDef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(true, helper, sb); - fnc.CreateAssemblyQualifiedName(typeDef); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// Returns the assembly where this type is defined - /// - /// The TypeDef - /// A or null if none found - public static IAssembly DefinitionAssembly(TypeDef typeDef) => - new FullNameFactory().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) => - new FullNameFactory().GetOwnerModule(typeDef); - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeSpec, true); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateName(typeSpec); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(isReflection, helper, sb); - fnc.CreateFullName(typeSpec); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(true, helper, sb); - fnc.CreateAssemblyQualifiedName(typeSpec); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// Returns the assembly where this type is defined - /// - /// The TypeSpec - /// A or null if none found - public static IAssembly DefinitionAssembly(TypeSpec typeSpec) => - new FullNameFactory().GetDefinitionAssembly(typeSpec); - - /// - /// Gets the scope type - /// - /// The TypeSpec - /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(TypeSpec typeSpec) => - new FullNameFactory().GetScopeType(typeSpec); - - /// - /// Gets the scope - /// - /// The TypeSpec - /// The or null if none found - public static IScope Scope(TypeSpec typeSpec) => - new FullNameFactory().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) => - new FullNameFactory().GetOwnerModule(typeSpec); - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(typeSig, true); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateName(typeSig); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper 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 - /// - /// 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, IFullNameFactoryHelper helper, IList typeGenArgs, IList methodGenArgs, StringBuilder sb) { - var fnc = new FullNameFactory(isReflection, helper, sb); - if (typeGenArgs is not null || methodGenArgs is not null) - fnc.genericArguments = new GenericArguments(); - if (typeGenArgs is not null) - fnc.genericArguments.PushTypeArgs(typeGenArgs); - if (methodGenArgs is not null) - fnc.genericArguments.PushMethodArgs(methodGenArgs); - fnc.CreateFullName(typeSig); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(true, helper, sb); - fnc.CreateAssemblyQualifiedName(typeSig); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// Returns the assembly where this type is defined - /// - /// The TypeSig - /// A or null if none found - public static IAssembly DefinitionAssembly(TypeSig typeSig) => - new FullNameFactory().GetDefinitionAssembly(typeSig); - - /// - /// Gets the scope - /// - /// The TypeSig - /// The or null if none found - public static IScope Scope(TypeSig typeSig) => - new FullNameFactory().GetScope(typeSig); - - /// - /// Gets the scope type - /// - /// The TypeSig - /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(TypeSig typeSig) => - new FullNameFactory().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) => - new FullNameFactory().GetOwnerModule(typeSig); - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateNamespace(exportedType, true); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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 = null) => - 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 FullNameFactory(isReflection, null, sb); - fnc.CreateName(exportedType); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(isReflection, helper, sb); - fnc.CreateFullName(exportedType); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// 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, IFullNameFactoryHelper helper = null, StringBuilder sb = null) => - 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, IFullNameFactoryHelper helper, StringBuilder sb) { - var fnc = new FullNameFactory(true, helper, sb); - fnc.CreateAssemblyQualifiedName(exportedType); - return fnc.sb ?? new StringBuilder(); - } - - /// - /// Returns the assembly where this type is defined - /// - /// The ExportedType - /// A or null if none found - public static IAssembly DefinitionAssembly(ExportedType exportedType) => - new FullNameFactory().GetDefinitionAssembly(exportedType); - - /// - /// Gets the scope type - /// - /// The ExportedType - /// The scope type or null if none found - public static ITypeDefOrRef ScopeType(ExportedType exportedType) => - new FullNameFactory().GetScopeType(exportedType); - - /// - /// Gets the scope - /// - /// The ExportedType - /// The or null if none found - public static IScope Scope(ExportedType exportedType) => - new FullNameFactory().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) => - 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) { - this.sb = sb ?? new StringBuilder(); - this.isReflection = isReflection; - this.helper = helper; - genericArguments = null; - recursionCounter = new RecursionCounter(); - } - - bool MustUseAssemblyName(IType type) { - if (helper is null) - return true; - return helper.MustUseAssemblyName(GetDefinitionType(type)); - } - - IType GetDefinitionType(IType type) { - if (!recursionCounter.Increment()) - return type; - - if (type is TypeSpec ts) - type = ts.TypeSig; - - if (type is TypeSig sig) { - GenericInstSig gis; - if (sig is TypeDefOrRefSig tdr) - type = GetDefinitionType(tdr.TypeDefOrRef); - else if ((gis = sig as GenericInstSig) is not null) - type = GetDefinitionType(gis.GenericType); - else - type = GetDefinitionType(sig.Next); - } - - recursionCounter.Decrement(); - return type; - } - - void CreateFullName(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef) - CreateFullName((TypeRef)typeDefOrRef); - else if (typeDefOrRef is TypeDef) - CreateFullName((TypeDef)typeDefOrRef); - else if (typeDefOrRef is TypeSpec) - CreateFullName((TypeSpec)typeDefOrRef); - else - sb.Append(NULLVALUE); - } - - void CreateNamespace(ITypeDefOrRef typeDefOrRef, bool onlyNamespace) { - if (typeDefOrRef is TypeRef) - CreateNamespace((TypeRef)typeDefOrRef, onlyNamespace); - else if (typeDefOrRef is TypeDef) - CreateNamespace((TypeDef)typeDefOrRef, onlyNamespace); - else if (typeDefOrRef is TypeSpec) - CreateNamespace((TypeSpec)typeDefOrRef, onlyNamespace); - else - sb.Append(NULLVALUE); - } - - void CreateName(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef) - CreateName((TypeRef)typeDefOrRef); - else if (typeDefOrRef is TypeDef) - CreateName((TypeDef)typeDefOrRef); - else if (typeDefOrRef is TypeSpec) - CreateName((TypeSpec)typeDefOrRef); - else - sb.Append(NULLVALUE); - } - - void CreateAssemblyQualifiedName(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef) - CreateAssemblyQualifiedName((TypeRef)typeDefOrRef); - else if (typeDefOrRef is TypeDef) - CreateAssemblyQualifiedName((TypeDef)typeDefOrRef); - else if (typeDefOrRef is TypeSpec) - CreateAssemblyQualifiedName((TypeSpec)typeDefOrRef); - else - sb.Append(NULLVALUE); - } - - void CreateAssemblyQualifiedName(TypeRef typeRef) { - if (typeRef is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - CreateFullName(typeRef); - if (MustUseAssemblyName(typeRef)) { - sb.Append(", "); - CreateAssemblyFullName(GetDefinitionAssembly(typeRef), true); - } - - recursionCounter.Decrement(); - } - - void CreateFullName(TypeRef typeRef) { - if (typeRef is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - if (typeRef.ResolutionScope is TypeRef declaringTypeRef) { - CreateFullName(declaringTypeRef); - AddNestedTypeSeparator(); - } - - if (AddNamespace(typeRef.Namespace, false)) - sb.Append('.'); - AddName(typeRef.Name); - - recursionCounter.Decrement(); - } - - void CreateNamespace(TypeRef typeRef, bool onlyNamespace) { - if (typeRef is null) { - sb.Append(NULLVALUE); - return; - } - AddNamespace(typeRef.Namespace, onlyNamespace); - } - - void CreateName(TypeRef typeRef) { - if (typeRef is null) { - sb.Append(NULLVALUE); - return; - } - AddName(typeRef.Name); - } - - void CreateAssemblyQualifiedName(TypeDef typeDef) { - if (typeDef is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - CreateFullName(typeDef); - if (MustUseAssemblyName(typeDef)) { - sb.Append(", "); - CreateAssemblyFullName(GetDefinitionAssembly(typeDef), true); - } - - recursionCounter.Decrement(); - } - - void CreateFullName(TypeDef typeDef) { - if (typeDef is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - var declaringTypeDef = typeDef.DeclaringType; - if (declaringTypeDef is not null) { - CreateFullName(declaringTypeDef); - AddNestedTypeSeparator(); - } - - if (AddNamespace(typeDef.Namespace, false)) - sb.Append('.'); - AddName(typeDef.Name); - - recursionCounter.Decrement(); - } - - void CreateNamespace(TypeDef typeDef, bool onlyNamespace) { - if (typeDef is null) { - sb.Append(NULLVALUE); - return; - } - AddNamespace(typeDef.Namespace, onlyNamespace); - } - - void CreateName(TypeDef typeDef) { - if (typeDef is null) { - sb.Append(NULLVALUE); - return; - } - AddName(typeDef.Name); - } - - void CreateAssemblyQualifiedName(TypeSpec typeSpec) { - if (typeSpec is null) { - sb.Append(NULLVALUE); - return; - } - CreateAssemblyQualifiedName(typeSpec.TypeSig); - } - - void CreateFullName(TypeSpec typeSpec) { - if (typeSpec is null) { - sb.Append(NULLVALUE); - return; - } - CreateFullName(typeSpec.TypeSig); - } - - void CreateNamespace(TypeSpec typeSpec, bool onlyNamespace) { - if (typeSpec is null) { - sb.Append(NULLVALUE); - return; - } - CreateNamespace(typeSpec.TypeSig, onlyNamespace); - } - - void CreateName(TypeSpec typeSpec) { - if (typeSpec is null) { - sb.Append(NULLVALUE); - return; - } - CreateName(typeSpec.TypeSig); - } - - - void CreateAssemblyQualifiedName(TypeSig typeSig) { - if (typeSig is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - CreateFullName(typeSig); - if (MustUseAssemblyName(typeSig)) { - sb.Append(", "); - CreateAssemblyFullName(GetDefinitionAssembly(typeSig), true); - } - - recursionCounter.Decrement(); - } - - void CreateFullName(TypeSig typeSig) => CreateTypeSigName(typeSig, TYPESIG_NAMESPACE | TYPESIG_NAME); - 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) { - if (genericArguments is null) - return typeSig; - var newTypeSig = genericArguments.Resolve(typeSig); - if (newTypeSig != typeSig) - genericArguments = null; - return newTypeSig; - } - - 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); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - var old = genericArguments; - typeSig = ReplaceGenericArg(typeSig); - - bool createNamespace = (flags & TYPESIG_NAMESPACE) != 0; - bool createName = (flags & TYPESIG_NAME) != 0; - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - if (createNamespace && createName) - CreateFullName(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - else if (createNamespace) - CreateNamespace(((TypeDefOrRefSig)typeSig).TypeDefOrRef, (flags & TYPESIG_ONLY_NAMESPACE) != 0); - else if (createName) - CreateName(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Ptr: - CreateTypeSigName(typeSig.Next, flags); - if (createName) - sb.Append('*'); - break; - - case ElementType.ByRef: - CreateTypeSigName(typeSig.Next, flags); - if (createName) - sb.Append('&'); - break; - - case ElementType.Array: - CreateTypeSigName(typeSig.Next, flags); - if (createName) { - 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) - sb.Append('*'); - else for (int i = 0; i < (int)rank; i++) { - if (i != 0) - sb.Append(','); - 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; - if (lower != NO_LOWER) { - sb.Append(lower); - sb.Append(".."); - if (size != NO_SIZE) - sb.Append(lower + (int)size - 1); - else - sb.Append('.'); - } - } - } - sb.Append(']'); - } - break; - - case ElementType.SZArray: - CreateTypeSigName(typeSig.Next, flags); - if (createName) - sb.Append("[]"); - break; - - case ElementType.CModReqd: - CreateTypeSigName(typeSig.Next, flags); - if (!isReflection && createName) { - sb.Append(" modreq("); - if (createNamespace) - CreateFullName(((ModifierSig)typeSig).Modifier); - else - CreateName(((ModifierSig)typeSig).Modifier); - sb.Append(")"); - } - break; - - case ElementType.CModOpt: - CreateTypeSigName(typeSig.Next, flags); - if (!isReflection && createName) { - sb.Append(" modopt("); - if (createNamespace) - CreateFullName(((ModifierSig)typeSig).Modifier); - else - CreateName(((ModifierSig)typeSig).Modifier); - sb.Append(")"); - } - break; - - case ElementType.Pinned: - CreateTypeSigName(typeSig.Next, flags); - break; - - case ElementType.ValueArray: - CreateTypeSigName(typeSig.Next, flags); - if (createName) { - var valueArraySig = (ValueArraySig)typeSig; - sb.Append(" ValueArray("); - sb.Append(valueArraySig.Size); - sb.Append(')'); - } - break; - - case ElementType.Module: - CreateTypeSigName(typeSig.Next, flags); - if (createName) { - var moduleSig = (ModuleSig)typeSig; - sb.Append(" Module("); - sb.Append(moduleSig.Index); - sb.Append(')'); - } - break; - - case ElementType.GenericInst: - var genericInstSig = (GenericInstSig)typeSig; - var typeGenArgs = genericInstSig.GenericArguments; - CreateTypeSigName(genericInstSig.GenericType, flags); - if (createNamespace && createName) { - if (isReflection) { - sb.Append('['); - int i = -1; - int count = typeGenArgs.Count; - for (int j = 0; j < count; j++) { - var genArg = typeGenArgs[j]; - i++; - if (i != 0) - sb.Append(','); - - bool mustWriteAssembly = MustUseAssemblyName(genArg); - if (mustWriteAssembly) - sb.Append('['); - - CreateFullName(genArg); - - if (mustWriteAssembly) { - sb.Append(", "); - CreateAssemblyFullName(GetDefinitionAssembly(genArg), true, true); - sb.Append(']'); - } - } - sb.Append(']'); - } - else { - sb.Append('<'); - int i = -1; - int count = typeGenArgs.Count; - for (int j = 0; j < count; j++) { - var genArg = typeGenArgs[j]; - i++; - if (i != 0) - sb.Append(','); - CreateFullName(genArg); - } - sb.Append('>'); - } - } - break; - - case ElementType.Var: - case ElementType.MVar: - if (createName) { - var gs = (GenericSig)typeSig; - var gp = gs.GenericParam; - if (gp is null || !AddName(gp.Name)) { - sb.Append(gs.IsMethodVar ? "!!" : "!"); - sb.Append(gs.Number); - } - } - break; - - case ElementType.FnPtr: - if (createName) { - if (isReflection) - sb.Append("(fnptr)"); - else - CreateMethodFullName(null, null, ((FnPtrSig)typeSig).MethodSig, null); - } - break; - - case ElementType.Sentinel: - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - break; - } - - genericArguments = old; - recursionCounter.Decrement(); - } - - void CreateAssemblyQualifiedName(ExportedType exportedType) { - if (exportedType is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - CreateFullName(exportedType); - if (MustUseAssemblyName(exportedType)) { - sb.Append(", "); - CreateAssemblyFullName(GetDefinitionAssembly(exportedType), true); - } - - recursionCounter.Decrement(); - } - - void CreateFullName(ExportedType exportedType) { - if (exportedType is null) { - sb.Append(NULLVALUE); - return; - } - if (!recursionCounter.Increment()) { - sb.Append(RECURSION_ERROR_RESULT_STRING); - return; - } - - if (exportedType.Implementation is ExportedType declaringExportedType) { - CreateFullName(declaringExportedType); - AddNestedTypeSeparator(); - } - - if (AddNamespace(exportedType.TypeNamespace, false)) - sb.Append('.'); - AddName(exportedType.TypeName); - - recursionCounter.Decrement(); - } - - void CreateNamespace(ExportedType exportedType, bool onlyNamespace) { - if (exportedType is null) { - sb.Append(NULLVALUE); - return; - } - AddNamespace(exportedType.TypeNamespace, onlyNamespace); - } - - void CreateName(ExportedType exportedType) { - if (exportedType is null) { - sb.Append(NULLVALUE); - return; - } - AddName(exportedType.TypeName); - } - - 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); - } - return sb.ToString(); - } - - void AddNestedTypeSeparator() { - if (isReflection) - sb.Append('+'); - else - sb.Append('/'); - } - - bool AddNamespace(UTF8String @namespace, bool onlyNamespace) { - if (UTF8String.IsNullOrEmpty(@namespace)) - return false; - // 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; - } - - bool AddName(UTF8String name) { - if (UTF8String.IsNullOrEmpty(name)) - return false; - AddIdentifier(name.String); - return true; - } - - void CreateAssemblyFullName(IAssembly assembly, bool useToken, bool escapeClosingBracket = false) { - if (assembly is null) { - sb.Append(NULLVALUE); - 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) { - if (isReflection) { - // Periods are not escaped by Reflection, even if they're part of a type name. - foreach (var c in id) { - switch (c) { - case ',': - case '+': - case '&': - case '*': - case '[': - case ']': - case '\\': - sb.Append('\\'); - break; - } - sb.Append(c); - } - } - else - sb.Append(id); - } - - IAssembly GetDefinitionAssembly(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef tr) - return GetDefinitionAssembly(tr); - - if (typeDefOrRef is TypeDef td) - return GetDefinitionAssembly(td); - - if (typeDefOrRef is TypeSpec ts) - return GetDefinitionAssembly(ts); - - return null; - } - - IScope GetScope(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef tr) - return GetScope(tr); - - if (typeDefOrRef is TypeDef td) - return td.Scope; - - if (typeDefOrRef is TypeSpec ts) - return GetScope(ts); - - return null; - } - - ITypeDefOrRef GetScopeType(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef tr) - return tr; - - if (typeDefOrRef is TypeDef td) - return td; - - if (typeDefOrRef is TypeSpec ts) - return GetScopeType(ts); - - return null; - } - - ModuleDef GetOwnerModule(ITypeDefOrRef typeDefOrRef) { - if (typeDefOrRef is TypeRef tr) - return GetOwnerModule(tr); - - if (typeDefOrRef is TypeDef td) - return GetOwnerModule(td); - - if (typeDefOrRef is TypeSpec ts) - return GetOwnerModule(ts); - - return null; - } - - IAssembly GetDefinitionAssembly(TypeRef typeRef) { - if (typeRef is null) - return null; - if (!recursionCounter.Increment()) - return null; - IAssembly result; - - var scope = typeRef.ResolutionScope; - if (scope is null) - result = null; //TODO: Check ownerModule's ExportedType table - else if (scope is TypeRef) - result = GetDefinitionAssembly((TypeRef)scope); - else if (scope is AssemblyRef) - result = (AssemblyRef)scope; - else if (scope is ModuleRef) { - var ownerModule = GetOwnerModule(typeRef); - result = ownerModule?.Assembly; - } - else if (scope is ModuleDef) - result = ((ModuleDef)scope).Assembly; - else - result = null; // Should never be reached - - recursionCounter.Decrement(); - return result; - } - - IScope GetScope(TypeRef typeRef) { - if (typeRef is null) - return null; - if (!recursionCounter.Increment()) - return null; - IScope result; - TypeRef tr; - AssemblyRef asmRef; - ModuleRef modRef; - ModuleDef modDef; - - var scope = typeRef.ResolutionScope; - if (scope is null) - result = null; //TODO: Check ownerModule's ExportedType table - else if ((tr = scope as TypeRef) is not null) - result = GetScope(tr); - else if ((asmRef = scope as AssemblyRef) is not null) - result = asmRef; - else if ((modRef = scope as ModuleRef) is not null) - result = modRef; - else if ((modDef = scope as ModuleDef) is not null) - result = modDef; - else - result = null; // Should never be reached - - recursionCounter.Decrement(); - return result; - } - - ModuleDef GetOwnerModule(TypeRef typeRef) { - if (typeRef is null) - return null; - return typeRef.Module; - } - - IAssembly GetDefinitionAssembly(TypeDef typeDef) => GetOwnerModule(typeDef)?.Assembly; - - ModuleDef GetOwnerModule(TypeDef typeDef) { - 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 is null) { - result = typeDef.Module2; - break; - } - typeDef = declaringType; - } - - return result; - } - - IAssembly GetDefinitionAssembly(TypeSpec typeSpec) { - if (typeSpec is null) - return null; - return GetDefinitionAssembly(typeSpec.TypeSig); - } - - IScope GetScope(TypeSpec typeSpec) { - if (typeSpec is null) - return null; - return GetScope(typeSpec.TypeSig); - } - - ITypeDefOrRef GetScopeType(TypeSpec typeSpec) { - if (typeSpec is null) - return null; - return GetScopeType(typeSpec.TypeSig); - } - - ModuleDef GetOwnerModule(TypeSpec typeSpec) { - if (typeSpec is null) - return null; - return GetOwnerModule(typeSpec.TypeSig); - } - - IAssembly GetDefinitionAssembly(TypeSig typeSig) { - if (typeSig is null) - return null; - if (!recursionCounter.Increment()) - return null; - IAssembly result; - - var old = genericArguments; - typeSig = ReplaceGenericArg(typeSig); - - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - result = GetDefinitionAssembly(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.SZArray: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Pinned: - case ElementType.ValueArray: - case ElementType.Module: - result = GetDefinitionAssembly(typeSig.Next); - break; - - case ElementType.GenericInst: - var genericInstSig = (GenericInstSig)typeSig; - var genericType = genericInstSig.GenericType; - result = GetDefinitionAssembly(genericType?.TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - case ElementType.FnPtr: - case ElementType.Sentinel: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = null; - break; - } - - genericArguments = old; - recursionCounter.Decrement(); - return result; - } - - ITypeDefOrRef GetScopeType(TypeSig typeSig) { - if (typeSig is null) - return null; - if (!recursionCounter.Increment()) - return null; - ITypeDefOrRef result; - - var old = genericArguments; - typeSig = ReplaceGenericArg(typeSig); - - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - result = GetScopeType(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.SZArray: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Pinned: - case ElementType.ValueArray: - case ElementType.Module: - result = GetScopeType(typeSig.Next); - break; - - case ElementType.GenericInst: - result = GetScopeType(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - case ElementType.FnPtr: - case ElementType.Sentinel: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = null; - break; - } - - genericArguments = old; - recursionCounter.Decrement(); - return result; - } - - IScope GetScope(TypeSig typeSig) { - if (typeSig is null) - return null; - if (!recursionCounter.Increment()) - return null; - IScope result; - - var old = genericArguments; - typeSig = ReplaceGenericArg(typeSig); - - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - result = GetScope(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.SZArray: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Pinned: - case ElementType.ValueArray: - case ElementType.Module: - result = GetScope(typeSig.Next); - break; - - case ElementType.GenericInst: - result = GetScope(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - case ElementType.FnPtr: - case ElementType.Sentinel: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = null; - break; - } - - genericArguments = old; - recursionCounter.Decrement(); - return result; - } - - ModuleDef GetOwnerModule(TypeSig typeSig) { - if (typeSig is null) - return null; - if (!recursionCounter.Increment()) - return null; - ModuleDef result; - - var old = genericArguments; - typeSig = ReplaceGenericArg(typeSig); - - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - result = GetOwnerModule(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.SZArray: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Pinned: - case ElementType.ValueArray: - case ElementType.Module: - result = GetOwnerModule(typeSig.Next); - break; - - case ElementType.GenericInst: - result = GetOwnerModule(((GenericInstSig)typeSig).GenericType?.TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - case ElementType.FnPtr: - case ElementType.Sentinel: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = null; - break; - } - - genericArguments = old; - recursionCounter.Decrement(); - return result; - } - - IAssembly GetDefinitionAssembly(ExportedType exportedType) { - if (exportedType is null) - return null; - if (!recursionCounter.Increment()) - return null; - IAssembly result; - AssemblyRef asmRef; - - var scope = exportedType.Implementation; - if (scope is ExportedType et) - result = GetDefinitionAssembly(et); - else if ((asmRef = scope as AssemblyRef) is not null) - result = asmRef; - else if (scope is FileDef) { - var ownerModule = GetOwnerModule(exportedType); - result = ownerModule?.Assembly; - } - else - result = null; - - recursionCounter.Decrement(); - return result; - } - - ITypeDefOrRef GetScopeType(ExportedType exportedType) => null; - - IScope GetScope(ExportedType exportedType) { - if (exportedType is null) - return null; - if (!recursionCounter.Increment()) - return null; - IScope result; - AssemblyRef asmRef; - FileDef file; - - var scope = exportedType.Implementation; - if (scope is ExportedType et) - result = GetScope(et); - else if ((asmRef = scope as AssemblyRef) is not null) - result = asmRef; - 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 not null) - ownerModule.UpdateRowId(modRef); - result = modRef; - } - else - result = null; - - recursionCounter.Decrement(); - return result; - } - - ModuleDef GetOwnerModule(ExportedType exportedType) { - if (exportedType is null) - return null; - return exportedType.Module; - } - - void CreateFieldFullName(string declaringType, string name, FieldSig fieldSig) { - CreateFullName(fieldSig?.Type); - sb.Append(' '); - - if (declaringType is not null) { - sb.Append(declaringType); - sb.Append("::"); - } - if (name is not null) - sb.Append(name); - } - - void CreateMethodFullName(string declaringType, string name, MethodBaseSig methodSig, MethodDef gppMethod) { - if (methodSig is null) { - sb.Append(NULLVALUE); - return; - } - - CreateFullName(methodSig.RetType); - sb.Append(' '); - if (declaringType is not null) { - sb.Append(declaringType); - sb.Append("::"); - } - if (name is not null) - sb.Append(name); - - 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(','); - CreateFullName(new GenericMVar(i, gppMethod)); - } - sb.Append('>'); - } - sb.Append('('); - int count = PrintMethodArgList(methodSig.Params, false, false); - PrintMethodArgList(methodSig.ParamsAfterSentinel, count > 0, true); - sb.Append(')'); - } - - int PrintMethodArgList(IList args, bool hasPrintedArgs, bool isAfterSentinel) { - if (args is null) - return 0; - if (isAfterSentinel) { - if (hasPrintedArgs) - sb.Append(','); - sb.Append("..."); - hasPrintedArgs = true; - } - int count = 0; - int argsCount = args.Count; - for (int i = 0; i < argsCount; i++) { - var arg = args[i]; - count++; - if (hasPrintedArgs) - sb.Append(','); - CreateFullName(arg); - hasPrintedArgs = true; - } - return count; - } - - 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); - sb.Append(' '); - if (declaringType is not null) { - sb.Append(declaringType); - sb.Append("::"); - } - if (!UTF8String.IsNull(name)) - sb.Append(UTF8String.ToSystemString(name)); - } - - /// - public override string ToString() => Result; - } -} diff --git a/Plugins/dnlib/DotNet/GenericArguments.cs b/Plugins/dnlib/DotNet/GenericArguments.cs deleted file mode 100644 index 866b5f7..0000000 --- a/Plugins/dnlib/DotNet/GenericArguments.cs +++ /dev/null @@ -1,120 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - readonly struct GenericArgumentsStack { - readonly List> argsStack; - readonly bool isTypeVar; - - /// - /// Constructor - /// - /// true if it's for generic types, false if generic methods - public GenericArgumentsStack(bool isTypeVar) { - argsStack = new List>(); - this.isTypeVar = isTypeVar; - } - - /// - /// Pushes generic arguments - /// - /// The generic arguments - public void Push(IList args) => argsStack.Add(args); - - /// - /// Pops generic arguments - /// - /// The popped generic arguments - public IList Pop() { - int index = argsStack.Count - 1; - var result = argsStack[index]; - argsStack.RemoveAt(index); - return result; - } - - /// - /// Resolves a generic argument - /// - /// Generic variable number - /// A or null if none was found - public TypeSig Resolve(uint number) { - TypeSig result = null; - for (int i = argsStack.Count - 1; i >= 0; i--) { - var args = argsStack[i]; - if (number >= args.Count) - return null; - var typeSig = args[(int)number]; - var gvar = typeSig as GenericSig; - if (gvar is null || gvar.IsTypeVar != isTypeVar) - return typeSig; - result = gvar; - number = gvar.Number; - } - return result; - } - } - - /// - /// Replaces generic type/method var with its generic argument - /// - sealed class GenericArguments { - GenericArgumentsStack typeArgsStack = new GenericArgumentsStack(true); - GenericArgumentsStack methodArgsStack = new GenericArgumentsStack(false); - - /// - /// Pushes generic arguments - /// - /// The generic arguments - public void PushTypeArgs(IList typeArgs) => typeArgsStack.Push(typeArgs); - - /// - /// Pops generic arguments - /// - /// The popped generic arguments - public IList PopTypeArgs() => typeArgsStack.Pop(); - - /// - /// Pushes generic arguments - /// - /// The generic arguments - public void PushMethodArgs(IList methodArgs) => methodArgsStack.Push(methodArgs); - - /// - /// Pops generic arguments - /// - /// The popped generic arguments - public IList PopMethodArgs() => methodArgsStack.Pop(); - - /// - /// Replaces a generic type/method var with its generic argument (if any). If - /// isn't a generic type/method var or if it can't - /// be resolved, it itself is returned. Else the resolved type is returned. - /// - /// Type signature - /// New which is never null unless - /// is null - public TypeSig Resolve(TypeSig typeSig) { - if (typeSig is null) - return null; - - var sig = typeSig; - - if (sig is GenericMVar genericMVar) { - var newSig = methodArgsStack.Resolve(genericMVar.Number); - if (newSig is null || newSig == sig) - return sig; - return newSig; - } - - if (sig is GenericVar genericVar) { - var newSig = typeArgsStack.Resolve(genericVar.Number); - if (newSig is null || newSig == sig) - return sig; - return newSig; - } - - return sig; - } - } -} diff --git a/Plugins/dnlib/DotNet/GenericParam.cs b/Plugins/dnlib/DotNet/GenericParam.cs deleted file mode 100644 index 82cb469..0000000 --- a/Plugins/dnlib/DotNet/GenericParam.cs +++ /dev/null @@ -1,431 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Threading; -using dnlib.Utils; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the GenericParam table - /// - [DebuggerDisplay("{Name.String}")] - public abstract class GenericParam : IHasCustomAttribute, IHasCustomDebugInformation, IMemberDef, IListListener { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.GenericParam, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 19; - - /// - /// Gets the owner type/method - /// - public ITypeOrMethodDef Owner { - get => owner; - internal set => owner = value; - } - /// - protected ITypeOrMethodDef owner; - - /// - /// Gets the declaring type or null if none or if is - /// not a - /// - public TypeDef DeclaringType => 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 => owner as MethodDef; - - /// - /// From column GenericParam.Number - /// - public ushort Number { - get => number; - set => number = value; - } - /// - protected ushort number; - - /// - /// From column GenericParam.Flags - /// - public GenericParamAttributes Flags { - get => (GenericParamAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column GenericParam.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column GenericParam.Kind (v1.1 only) - /// - public ITypeDefOrRef Kind { - get => kind; - set => kind = value; - } - /// - protected ITypeDefOrRef kind; - - /// - /// Gets the generic param constraints - /// - public IList GenericParamConstraints { - get { - if (genericParamConstraints is null) - InitializeGenericParamConstraints(); - return genericParamConstraints; - } - } - /// - protected LazyList genericParamConstraints; - /// Initializes - protected virtual void InitializeGenericParamConstraints() => - Interlocked.CompareExchange(ref genericParamConstraints, new LazyList(this), null); - - /// - /// 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 => 19; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// true if is not empty - /// - public bool HasGenericParamConstraints => GenericParamConstraints.Count > 0; - - /// - public ModuleDef Module => owner?.Module; - - /// - 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: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(GenericParamAttributes andMask, GenericParamAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, GenericParamAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets variance (non, contra, co) - /// - public GenericParamAttributes Variance { - get => (GenericParamAttributes)attributes & GenericParamAttributes.VarianceMask; - set => ModifyAttributes(~GenericParamAttributes.VarianceMask, value & GenericParamAttributes.VarianceMask); - } - - /// - /// true if is set - /// - public bool IsNonVariant => Variance == GenericParamAttributes.NonVariant; - - /// - /// true if is set - /// - public bool IsCovariant => Variance == GenericParamAttributes.Covariant; - - /// - /// true if is set - /// - public bool IsContravariant => Variance == GenericParamAttributes.Contravariant; - - /// - /// Gets/sets the special constraint - /// - public GenericParamAttributes SpecialConstraint { - get => (GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask; - set => ModifyAttributes(~GenericParamAttributes.SpecialConstraintMask, value & GenericParamAttributes.SpecialConstraintMask); - } - - /// - /// true if there are no special constraints - /// - public bool HasNoSpecialConstraint => ((GenericParamAttributes)attributes & GenericParamAttributes.SpecialConstraintMask) == GenericParamAttributes.NoSpecialConstraint; - - /// - /// Gets/sets the bit - /// - public bool HasReferenceTypeConstraint { - get => ((GenericParamAttributes)attributes & GenericParamAttributes.ReferenceTypeConstraint) != 0; - set => ModifyAttributes(value, GenericParamAttributes.ReferenceTypeConstraint); - } - - /// - /// Gets/sets the bit - /// - public bool HasNotNullableValueTypeConstraint { - get => ((GenericParamAttributes)attributes & GenericParamAttributes.NotNullableValueTypeConstraint) != 0; - set => ModifyAttributes(value, GenericParamAttributes.NotNullableValueTypeConstraint); - } - - /// - /// Gets/sets the bit - /// - public bool HasDefaultConstructorConstraint { - get => ((GenericParamAttributes)attributes & GenericParamAttributes.DefaultConstructorConstraint) != 0; - set => ModifyAttributes(value, GenericParamAttributes.DefaultConstructorConstraint); - } - - /// - void IListListener.OnLazyAdd(int index, ref GenericParamConstraint value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref GenericParamConstraint value) { -#if DEBUG - if (value.Owner != this) - throw new InvalidOperationException("Added generic param constraint's Owner != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, GenericParamConstraint value) { - 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; - } - - /// - void IListListener.OnRemove(int index, GenericParamConstraint value) => value.Owner = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var gpc in genericParamConstraints.GetEnumerable_NoLock()) - gpc.Owner = null; - } - - /// - public override string ToString() { - var o = owner; - if (o is TypeDef) - return $"!{number}"; - if (o is MethodDef) - return $"!!{number}"; - return $"??{number}"; - } - } - - /// - /// A GenericParam row created by the user and not present in the original .NET file - /// - public class GenericParamUser : GenericParam { - /// - /// Default constructor - /// - public GenericParamUser() { - } - - /// - /// Constructor - /// - /// The generic param number - public GenericParamUser(ushort number) - : this(number, 0) { - } - - /// - /// Constructor - /// - /// The generic param number - /// Flags - public GenericParamUser(ushort number, GenericParamAttributes flags) - : this(number, flags, UTF8String.Empty) { - } - - /// - /// Constructor - /// - /// The generic param number - /// Flags - /// Name - public GenericParamUser(ushort number, GenericParamAttributes flags, UTF8String name) { - genericParamConstraints = new LazyList(this); - this.number = number; - attributes = (int)flags; - this.name = name; - } - } - - /// - /// Created from a row in the GenericParam table - /// - sealed class GenericParamMD : GenericParam, 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.GenericParam, 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), GetGenericParamContext(owner), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - protected override void InitializeGenericParamConstraints() { - var list = readerModule.Metadata.GetGenericParamConstraintRidList(origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveGenericParamConstraint(list2[index], GetGenericParamContext(owner))); - Interlocked.CompareExchange(ref genericParamConstraints, tmp, null); - } - - static GenericParamContext GetGenericParamContext(ITypeOrMethodDef tmOwner) { - if (tmOwner is MethodDef md) - return GenericParamContext.Create(md); - return new GenericParamContext(tmOwner as TypeDef); - } - - /// - /// Constructor - /// - /// The module which contains this GenericParam row - /// Row ID - /// If is null - /// If is invalid - public GenericParamMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.GenericParamTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"GenericParam rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadGenericParamRow(origRid, out var row); - Debug.Assert(b); - number = row.Number; - attributes = row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - owner = readerModule.GetOwner(this); - if (row.Kind != 0) - kind = readerModule.ResolveTypeDefOrRef(row.Kind, GetGenericParamContext(owner)); - } - - internal GenericParamMD InitializeAll() { - MemberMDInitializer.Initialize(Owner); - MemberMDInitializer.Initialize(Number); - MemberMDInitializer.Initialize(Flags); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(Kind); - MemberMDInitializer.Initialize(CustomAttributes); - MemberMDInitializer.Initialize(GenericParamConstraints); - return this; - } - - /// - internal override void OnLazyAdd2(int index, ref GenericParamConstraint value) { - if (value.Owner != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadGenericParamConstraint(value.Rid, GetGenericParamContext(owner)).InitializeAll()); - value.Owner = this; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/GenericParamAttributes.cs b/Plugins/dnlib/DotNet/GenericParamAttributes.cs deleted file mode 100644 index 2b14fba..0000000 --- a/Plugins/dnlib/DotNet/GenericParamAttributes.cs +++ /dev/null @@ -1,31 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Generic parameter flags. See CorHdr.h/CorGenericParamAttr - /// - [Flags] - public enum GenericParamAttributes : ushort { - /// - VarianceMask = 0x0003, - /// - NonVariant = 0x0000, - /// - Covariant = 0x0001, - /// - Contravariant = 0x0002, - - /// - SpecialConstraintMask = 0x001C, - /// - NoSpecialConstraint = 0x0000, - /// type argument must be a reference type - ReferenceTypeConstraint = 0x0004, - /// type argument must be a value type but not Nullable - NotNullableValueTypeConstraint = 0x0008, - /// type argument must have a public default constructor - DefaultConstructorConstraint = 0x0010, - } -} diff --git a/Plugins/dnlib/DotNet/GenericParamConstraint.cs b/Plugins/dnlib/DotNet/GenericParamConstraint.cs deleted file mode 100644 index 1611a4b..0000000 --- a/Plugins/dnlib/DotNet/GenericParamConstraint.cs +++ /dev/null @@ -1,174 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the GenericParamConstraint table - /// - public abstract class GenericParamConstraint : IHasCustomAttribute, IHasCustomDebugInformation, IContainsGenericParameter { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.GenericParamConstraint, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 20; - - /// - /// Gets the owner generic param - /// - public GenericParam Owner { - get => owner; - internal set => owner = value; - } - /// - protected GenericParam owner; - - /// - /// From column GenericParamConstraint.Constraint - /// - public ITypeDefOrRef Constraint { - get => constraint; - set => constraint = value; - } - /// - protected ITypeDefOrRef constraint; - - /// - /// 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 => 20; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - } - - /// - /// A GenericParamConstraintAssembly row created by the user and not present in the original .NET file - /// - public class GenericParamConstraintUser : GenericParamConstraint { - /// - /// Default constructor - /// - public GenericParamConstraintUser() { - } - - /// - /// Constructor - /// - /// The constraint - public GenericParamConstraintUser(ITypeDefOrRef constraint) => this.constraint = constraint; - } - - /// - /// Created from a row in the GenericParamConstraint table - /// - sealed class GenericParamConstraintMD : GenericParamConstraint, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - - /// - public uint OrigRid => origRid; - - bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.GenericParamConstraint, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this GenericParamConstraint row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public GenericParamConstraintMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.GenericParamConstraintTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"GenericParamConstraint rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - bool b = readerModule.TablesStream.TryReadGenericParamConstraintRow(origRid, out var row); - Debug.Assert(b); - constraint = readerModule.ResolveTypeDefOrRef(row.Constraint, gpContext); - owner = readerModule.GetOwner(this); - } - - internal GenericParamConstraintMD InitializeAll() { - MemberMDInitializer.Initialize(Owner); - MemberMDInitializer.Initialize(Constraint); - MemberMDInitializer.Initialize(CustomAttributes); - return this; - } - } -} diff --git a/Plugins/dnlib/DotNet/GenericParamContext.cs b/Plugins/dnlib/DotNet/GenericParamContext.cs deleted file mode 100644 index 07b3304..0000000 --- a/Plugins/dnlib/DotNet/GenericParamContext.cs +++ /dev/null @@ -1,75 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Generic parameter context - /// - public readonly struct GenericParamContext { - /// - /// Type context - /// - public readonly TypeDef Type; - - /// - /// Method context - /// - public readonly MethodDef Method; - - /// - /// true if and are both null - /// - public bool IsEmpty => Type is null && Method is null; - - /// - /// Creates a new instance and initializes the - /// field to 's - /// and the field to . - /// - /// Method - /// A new instance - public static GenericParamContext Create(MethodDef method) { - if (method is null) - return new GenericParamContext(); - return new GenericParamContext(method.DeclaringType, method); - } - - /// - /// Creates a new instance and initializes the - /// field to and the field - /// to null - /// - /// Type - /// A new instance - public static GenericParamContext Create(TypeDef type) => new GenericParamContext(type); - - /// - /// Constructor - /// - /// Type context - public GenericParamContext(TypeDef type) { - Type = type; - Method = null; - } - - /// - /// Constructor. The field is set to null and NOT to - /// 's . Use - /// if you want that behavior. - /// - /// Method context - public GenericParamContext(MethodDef method) { - Type = null; - Method = method; - } - - /// - /// Constructor - /// - /// Type context - /// Method context - public GenericParamContext(TypeDef type, MethodDef method) { - Type = type; - Method = method; - } - } -} diff --git a/Plugins/dnlib/DotNet/IAssemblyResolver.cs b/Plugins/dnlib/DotNet/IAssemblyResolver.cs deleted file mode 100644 index 2d3eee4..0000000 --- a/Plugins/dnlib/DotNet/IAssemblyResolver.cs +++ /dev/null @@ -1,100 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Reflection; - -namespace dnlib.DotNet { - /// - /// Resolves assemblies - /// - public interface IAssemblyResolver { - /// - /// Finds and returns an - /// - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// An instance owned by the assembly resolver or - /// null if the assembly couldn't be found. - AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule); - } - - public static partial class Extensions { - /// - /// Finds and returns an - /// - /// this - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// 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 is null) - return null; - return self.Resolve(new AssemblyNameInfo(assembly), sourceModule); - } - - /// - /// Finds and returns an - /// - /// this - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// 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 is null) - return null; - return self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); - } - - /// - /// Finds and returns an - /// - /// this - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// 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 is null) - return null; - var asm = self.Resolve(assembly, sourceModule); - if (asm is not null) - return asm; - throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); - } - - /// - /// Finds and returns an - /// - /// this - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// 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 is null) - return null; - var asm = self.Resolve(new AssemblyNameInfo(assembly), sourceModule); - if (asm is not null) - return asm; - throw new AssemblyResolveException($"Could not resolve assembly: {assembly}"); - } - - /// - /// Finds and returns an - /// - /// this - /// The assembly to find - /// The module that needs to resolve an assembly or null - /// 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 is null) - return null; - var asm = self.Resolve(new AssemblyNameInfo(asmFullName), sourceModule); - if (asm is not null) - return asm; - throw new AssemblyResolveException($"Could not resolve assembly: {asmFullName}"); - } - } -} diff --git a/Plugins/dnlib/DotNet/ICodedToken.cs b/Plugins/dnlib/DotNet/ICodedToken.cs deleted file mode 100644 index c7dd08b..0000000 --- a/Plugins/dnlib/DotNet/ICodedToken.cs +++ /dev/null @@ -1,1089 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// The table row can be referenced by a MD token - /// - public interface IMDTokenProvider { - /// - /// Returns the metadata token - /// - MDToken MDToken { get; } - - /// - /// Gets/sets the row ID - /// - uint Rid { get; set; } - } - - /// - /// All *MD classes implement this interface. - /// - public interface IMDTokenProviderMD : IMDTokenProvider { - /// - /// Gets the original row ID - /// - uint OrigRid { get; } - } - - /// - /// An assembly. Implemented by , and - /// . - /// - public interface IAssembly : IFullName { - /// - /// The assembly version - /// - Version Version { get; set; } - - /// - /// Assembly flags - /// - AssemblyAttributes Attributes { get; set; } - - /// - /// Public key or public key token - /// - PublicKeyBase PublicKeyOrToken { get; } - - /// - /// Locale, aka culture - /// - UTF8String Culture { get; set; } - - /// - /// Gets the full name of the assembly but use a public key token - /// - string FullNameToken { get; } - - /// - /// Gets/sets the bit - /// - bool HasPublicKey { get; set; } - - /// - /// Gets/sets the processor architecture - /// - AssemblyAttributes ProcessorArchitecture { get; set; } - - /// - /// Gets/sets the processor architecture - /// - AssemblyAttributes ProcessorArchitectureFull { get; set; } - - /// - /// true if unspecified processor architecture - /// - bool IsProcessorArchitectureNone { get; } - - /// - /// true if neutral (PE32) architecture - /// - bool IsProcessorArchitectureMSIL { get; } - - /// - /// true if x86 (PE32) architecture - /// - bool IsProcessorArchitectureX86 { get; } - - /// - /// true if IA-64 (PE32+) architecture - /// - bool IsProcessorArchitectureIA64 { get; } - - /// - /// true if x64 (PE32+) architecture - /// - bool IsProcessorArchitectureX64 { get; } - - /// - /// true if ARM (PE32) architecture - /// - bool IsProcessorArchitectureARM { get; } - - /// - /// true if eg. reference assembly (not runnable) - /// - bool IsProcessorArchitectureNoPlatform { get; } - - /// - /// Gets/sets the bit - /// - bool IsProcessorArchitectureSpecified { get; set; } - - /// - /// Gets/sets the bit - /// - bool EnableJITcompileTracking { get; set; } - - /// - /// Gets/sets the bit - /// - bool DisableJITcompileOptimizer { get; set; } - - /// - /// Gets/sets the bit - /// - bool IsRetargetable { get; set; } - - /// - /// Gets/sets the content type - /// - AssemblyAttributes ContentType { get; set; } - - /// - /// true if content type is Default - /// - bool IsContentTypeDefault { get; } - - /// - /// true if content type is WindowsRuntime - /// - bool IsContentTypeWindowsRuntime { get; } - } - - public static partial class Extensions { - /// - /// Checks whether appears to be the core library (eg. - /// 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) { - if (asm is AssemblyDef asmDef) { - var manifestModule = asmDef.ManifestModule; - if (manifestModule is not null) { - var isCorModule = manifestModule.IsCoreLibraryModule; - if (isCorModule is not null) - return isCorModule.Value; - } - } - - string asmName; - return asm is not 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("netstandard", StringComparison.OrdinalIgnoreCase) || - asmName.Equals("corefx", StringComparison.OrdinalIgnoreCase)); - } - - /// - /// Converts to a instance - /// - /// The assembly - /// A new instance - public static AssemblyRef ToAssemblyRef(this IAssembly asm) { - 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 }; - } - - /// - /// Converts to a - /// - /// The type - /// 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 resolveToCheckValueType = true) { - if (type is null) - return null; - - var module = type.Module; - if (module is not null) { - var corLibType = module.CorLibTypes.GetCorLibTypeSig(type); - if (corLibType is not null) - return corLibType; - } - - var td = type as TypeDef; - if (td is not null) - return CreateClassOrValueType(type, td.IsValueType); - - if (type is TypeRef tr) { - if (resolveToCheckValueType) - td = tr.Resolve(); - return CreateClassOrValueType(type, td is null ? false : td.IsValueType); - } - - if (type is TypeSpec ts) - return ts.TypeSig; - - return null; - } - - static TypeSig CreateClassOrValueType(ITypeDefOrRef type, bool isValueType) { - if (isValueType) - return new ValueTypeSig(type); - return new ClassSig(type); - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static TypeDefOrRefSig TryGetTypeDefOrRefSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as TypeDefOrRefSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ClassOrValueTypeSig TryGetClassOrValueTypeSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassOrValueTypeSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ValueTypeSig TryGetValueTypeSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ValueTypeSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ClassSig TryGetClassSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ClassSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericSig TryGetGenericSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericVar TryGetGenericVar(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericVar; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericMVar TryGetGenericMVar(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericMVar; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericInstSig TryGetGenericInstSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as GenericInstSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static PtrSig TryGetPtrSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as PtrSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ByRefSig TryGetByRefSig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ByRefSig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ArraySig TryGetArraySig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as ArraySig; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static SZArraySig TryGetSZArraySig(this ITypeDefOrRef type) { - var ts = type as TypeSpec; - return ts is null ? null : ts.TypeSig.RemovePinnedAndModifiers() as SZArraySig; - } - - /// - /// Returns the base type of . Throws if we can't resolve - /// a . - /// - /// The type - /// The base type or null if there's no base type - public static ITypeDefOrRef GetBaseTypeThrow(this ITypeDefOrRef tdr) => tdr.GetBaseType(true); - - /// - /// Returns the base type of - /// - /// The type - /// true if we should throw if we can't - /// resolve a . false if we should ignore the error and - /// just return null. - /// 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 = false) { - if (tdr is TypeDef td) - return td.BaseType; - - if (tdr is TypeRef tr) { - td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); - return td?.BaseType; - } - - var ts = tdr as TypeSpec; - if (ts is null) - return null; - - var git = ts.TypeSig.ToGenericInstSig(); - if (git is not null) - tdr = git.GenericType?.TypeDefOrRef; - else - tdr = ts.TypeSig.ToTypeDefOrRefSig()?.TypeDefOrRef; - - td = tdr as TypeDef; - if (td is not null) - return td.BaseType; - - tr = tdr as TypeRef; - if (tr is not null) { - td = throwOnResolveFailure ? tr.ResolveThrow() : tr.Resolve(); - return td?.BaseType; - } - - return null; - } - - /// - /// Gets the scope type, resolves it, and returns the - /// - /// Type - /// A or null if input was null or if we - /// couldn't resolve the reference. - public static TypeDef ResolveTypeDef(this ITypeDefOrRef tdr) { - if (tdr is TypeDef td) - return td; - - if (tdr is TypeRef tr) - return tr.Resolve(); - - if (tdr is null) - return null; - tdr = tdr.ScopeType; - - td = tdr as TypeDef; - if (td is not null) - return td; - - tr = tdr as TypeRef; - if (tr is not null) - return tr.Resolve(); - - return null; - } - - /// - /// Gets the scope type, resolves it, and returns the - /// - /// Type - /// A instance. - /// If the type couldn't be resolved - public static TypeDef ResolveTypeDefThrow(this ITypeDefOrRef tdr) { - if (tdr is TypeDef td) - return td; - - if (tdr is TypeRef tr) - return tr.ResolveThrow(); - - if (tdr is null) - throw new TypeResolveException("Can't resolve a null pointer"); - tdr = tdr.ScopeType; - - td = tdr as TypeDef; - if (td is not null) - return td; - - tr = tdr as TypeRef; - if (tr is not null) - return tr.ResolveThrow(); - - throw new TypeResolveException($"Could not resolve type: {tdr} ({tdr?.DefinitionAssembly})"); - } - - /// - /// Resolves an to a . Returns null if it - /// was not possible to resolve it. See also - /// - /// Field to resolve - /// The or null if is - /// 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) { - if (field is FieldDef fd) - return fd; - - if (field is MemberRef mr) - return mr.ResolveField(); - - return null; - } - - /// - /// Resolves an to a and throws an exception if - /// it was not possible to resolve it. See also - /// - /// Field to resolve - /// The - public static FieldDef ResolveFieldDefThrow(this IField field) { - if (field is FieldDef fd) - return fd; - - if (field is MemberRef mr) - return mr.ResolveFieldThrow(); - - throw new MemberRefResolveException($"Could not resolve field: {field}"); - } - - /// - /// Resolves an to a . Returns null if it - /// was not possible to resolve it. See also . If - /// is a , then the - /// property is resolved and returned. - /// - /// Method to resolve - /// The or null if is - /// 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) { - if (method is MethodDef md) - return md; - - if (method is MemberRef mr) - return mr.ResolveMethod(); - - if (method is MethodSpec ms) { - md = ms.Method as MethodDef; - if (md is not null) - return md; - - mr = ms.Method as MemberRef; - if (mr is not null) - return mr.ResolveMethod(); - } - - return null; - } - - /// - /// Resolves an to a and throws an exception - /// if it was not possible to resolve it. See also . If - /// is a , then the - /// property is resolved and returned. - /// - /// Method to resolve - /// The - public static MethodDef ResolveMethodDefThrow(this IMethod method) { - if (method is MethodDef md) - return md; - - if (method is MemberRef mr) - return mr.ResolveMethodThrow(); - - if (method is MethodSpec ms) { - md = ms.Method as MethodDef; - if (md is not null) - return md; - - mr = ms.Method as MemberRef; - if (mr is not null) - return mr.ResolveMethodThrow(); - } - - throw new MemberRefResolveException($"Could not resolve method: {method}"); - } - - /// - /// Returns the definition assembly of a - /// - /// Member reference - /// - static internal IAssembly GetDefinitionAssembly(this MemberRef mr) { - if (mr is null) - return null; - var parent = mr.Class; - - if (parent is ITypeDefOrRef tdr) - return tdr.DefinitionAssembly; - - if (parent is ModuleRef) - return mr.Module?.Assembly; - - if (parent is MethodDef md) - return md.DeclaringType?.DefinitionAssembly; - - 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; - - /// - /// 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 - /// - /// this - /// Normal visible parameter index - /// - public static TypeSig GetParam(this IMethod method, int index) => method?.MethodSig.GetParams() is { } types && index >= 0 && index < types.Count ? types[index] : null; - } - - /// - /// Implemented by and , which are the only - /// valid managed entry point tokens. - /// - public interface IManagedEntryPoint : ICodedToken { - } - - /// - /// Interface to access a module def/ref - /// - public interface IModule : IScope, IFullName { - } - - /// - /// Type of scope - /// - public enum ScopeType { - /// - /// It's an instance - /// - AssemblyRef, - - /// - /// It's a instance - /// - ModuleRef, - - /// - /// It's a instance - /// - ModuleDef, - } - - /// - /// Implemented by modules and assemblies - /// - public interface IScope { - /// - /// Gets the scope type - /// - ScopeType ScopeType { get; } - - /// - /// Gets the scope name - /// - string ScopeName { get; } - } - - /// - /// Interface to get the full name of a type, field, or method - /// - public interface IFullName { - /// - /// Gets the full name - /// - string FullName { get; } - - /// - /// Simple name of implementer - /// - UTF8String Name { get; set; } - } - - /// - /// Implemented by all member refs and types - /// - public interface IOwnerModule { - /// - /// Gets the owner module - /// - ModuleDef Module { get; } - } - - /// - /// Methods to check whether the implementer is a type or a method. - /// - public interface IIsTypeOrMethod { - /// - /// true if it's a type - /// - bool IsType { get; } - - /// - /// true if it's a method - /// - bool IsMethod { get; } - } - - /// - /// Implemented by types, fields, methods, properties, events - /// - public interface IMemberRef : ICodedToken, IFullName, IOwnerModule, IIsTypeOrMethod { - /// - /// Gets the declaring type - /// - ITypeDefOrRef DeclaringType { get; } - - /// - /// true if it's a or a that's - /// referencing a field. - /// - bool IsField { get; } - - /// - /// true if it's a - /// - bool IsTypeSpec { get; } - - /// - /// true if it's a - /// - bool IsTypeRef { get; } - - /// - /// true if it's a - /// - bool IsTypeDef { get; } - - /// - /// true if it's a - /// - bool IsMethodSpec { get; } - - /// - /// true if it's a - /// - bool IsMethodDef { get; } - - /// - /// true if it's a - /// - bool IsMemberRef { get; } - - /// - /// true if it's a - /// - bool IsFieldDef { get; } - - /// - /// true if it's a - /// - bool IsPropertyDef { get; } - - /// - /// true if it's a - /// - bool IsEventDef { get; } - - /// - /// true if it's a - /// - bool IsGenericParam { get; } - } - - /// - /// All member definitions implement this interface: , - /// , , , - /// , and . - /// - public interface IMemberDef : IDnlibDef, IMemberRef { - /// - /// Gets the declaring type - /// - new TypeDef DeclaringType { get; } - } - - /// - /// Implemented by the following classes: , - /// , , , - /// , , , - /// and - /// - public interface IDnlibDef : ICodedToken, IFullName, IHasCustomAttribute { - } - - /// - /// Implemented by types and methods - /// - public interface IGenericParameterProvider : ICodedToken, IIsTypeOrMethod { - /// - /// Gets the number of generic parameters / arguments - /// - int NumberOfGenericParameters { get; } - } - - /// - /// Implemented by fields ( and ) - /// - public interface IField : ICodedToken, ITokenOperand, IFullName, IMemberRef { - /// - /// Gets/sets the field signature - /// - FieldSig FieldSig { get; set; } - } - - /// - /// Implemented by methods (, and ) - /// - public interface IMethod : ICodedToken, ITokenOperand, IFullName, IGenericParameterProvider, IMemberRef { - /// - /// Method signature - /// - MethodSig MethodSig { get; set; } - } - - /// - /// Implemented by tables that can be a token in the ldtoken instruction - /// - public interface ITokenOperand : ICodedToken { - } - - /// - /// The table row can be referenced by a coded token - /// - public interface ICodedToken : IMDTokenProvider { - } - - /// - /// TypeDefOrRef coded token interface - /// - public interface ITypeDefOrRef : ICodedToken, IHasCustomAttribute, IMemberRefParent, IType, ITokenOperand, IMemberRef { - /// - /// The coded token tag - /// - int TypeDefOrRefTag { get; } - } - - /// - /// HasConstant coded token interface - /// - public interface IHasConstant : ICodedToken, IHasCustomAttribute, IFullName { - /// - /// The coded token tag - /// - int HasConstantTag { get; } - - /// - /// Gets/sets the constant value - /// - Constant Constant { get; set; } - } - - /// - /// HasCustomAttribute coded token interface - /// - public interface IHasCustomAttribute : ICodedToken { - /// - /// The coded token tag - /// - int HasCustomAttributeTag { get; } - - /// - /// Gets all custom attributes - /// - CustomAttributeCollection CustomAttributes { get; } - - /// - /// true if is not empty - /// - bool HasCustomAttributes { get; } - } - - /// - /// HasFieldMarshal coded token interface - /// - public interface IHasFieldMarshal : ICodedToken, IHasCustomAttribute, IHasConstant, IFullName { - /// - /// The coded token tag - /// - int HasFieldMarshalTag { get; } - - /// - /// Gets/sets the marshal type - /// - MarshalType MarshalType { get; set; } - - /// - /// true if is not null - /// - bool HasMarshalType { get; } - } - - /// - /// HasDeclSecurity coded token interface - /// - public interface IHasDeclSecurity : ICodedToken, IHasCustomAttribute, IFullName { - /// - /// The coded token tag - /// - int HasDeclSecurityTag { get; } - - /// - /// Gets the permission sets - /// - IList DeclSecurities { get; } - - /// - /// true if is not empty - /// - bool HasDeclSecurities { get; } - } - - /// - /// MemberRefParent coded token interface - /// - public interface IMemberRefParent : ICodedToken, IHasCustomAttribute, IFullName { - /// - /// The coded token tag - /// - int MemberRefParentTag { get; } - } - - /// - /// HasSemantic coded token interface - /// - public interface IHasSemantic : ICodedToken, IHasCustomAttribute, IFullName, IMemberRef { - /// - /// The coded token tag - /// - int HasSemanticTag { get; } - } - - /// - /// MethodDefOrRef coded token interface - /// - public interface IMethodDefOrRef : ICodedToken, IHasCustomAttribute, ICustomAttributeType, IMethod { - /// - /// The coded token tag - /// - int MethodDefOrRefTag { get; } - } - - /// - /// MemberForwarded coded token interface - /// - public interface IMemberForwarded : ICodedToken, IHasCustomAttribute, IFullName, IMemberRef { - /// - /// The coded token tag - /// - int MemberForwardedTag { get; } - - /// - /// Gets/sets the impl map - /// - ImplMap ImplMap { get; set; } - - /// - /// true if is not null - /// - bool HasImplMap { get; } - } - - /// - /// Implementation coded token interface - /// - public interface IImplementation : ICodedToken, IHasCustomAttribute, IFullName { - /// - /// The coded token tag - /// - int ImplementationTag { get; } - } - - /// - /// CustomAttributeType coded token interface - /// - public interface ICustomAttributeType : ICodedToken, IHasCustomAttribute, IMethod { - /// - /// The coded token tag - /// - int CustomAttributeTypeTag { get; } - } - - /// - /// ResolutionScope coded token interface - /// - public interface IResolutionScope : ICodedToken, IHasCustomAttribute, IFullName { - /// - /// The coded token tag - /// - int ResolutionScopeTag { get; } - } - - /// - /// TypeOrMethodDef coded token interface - /// - public interface ITypeOrMethodDef : ICodedToken, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, IFullName, IMemberRef, IGenericParameterProvider { - /// - /// The coded token tag - /// - int TypeOrMethodDefTag { get; } - - /// - /// Gets the generic parameters - /// - IList GenericParameters { get; } - - /// - /// true if is not empty - /// - bool HasGenericParameters { get; } - } - - /// - /// HasCustomDebugInformation interface - /// - public interface IHasCustomDebugInformation { - /// - /// The custom debug information tag - /// - int HasCustomDebugInformationTag { get; } - - /// - /// Gets the custom debug infos - /// - IList CustomDebugInfos { get; } - - /// - /// true if is not empty - /// - bool HasCustomDebugInfos { get; } - } - - public static partial class Extensions { - /// - /// Converts a to a - /// - /// The sig - public static ITypeDefOrRef ToTypeDefOrRef(this TypeSig sig) { - if (sig is null) - return null; - if (sig is TypeDefOrRefSig tdrSig) - return tdrSig.TypeDefOrRef; - var module = sig.Module; - if (module is null) - return new TypeSpecUser(sig); - return module.UpdateRowId(new TypeSpecUser(sig)); - } - - /// - /// Returns true if it's an integer or a floating point type - /// - /// Type - /// - internal static bool IsPrimitive(this IType tdr) { - if (tdr is null) - return false; - if (!tdr.DefinitionAssembly.IsCorLib()) - return false; - - 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; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/ICorLibTypes.cs b/Plugins/dnlib/DotNet/ICorLibTypes.cs deleted file mode 100644 index ab924df..0000000 --- a/Plugins/dnlib/DotNet/ICorLibTypes.cs +++ /dev/null @@ -1,186 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Access to .NET core library's simple types - /// - public interface ICorLibTypes { - /// - /// Gets a System.Void - /// - CorLibTypeSig Void { get; } - - /// - /// Gets a System.Boolean - /// - CorLibTypeSig Boolean { get; } - - /// - /// Gets a System.Char - /// - CorLibTypeSig Char { get; } - - /// - /// Gets a System.SByte - /// - CorLibTypeSig SByte { get; } - - /// - /// Gets a System.Byte - /// - CorLibTypeSig Byte { get; } - - /// - /// Gets a System.Int16 - /// - CorLibTypeSig Int16 { get; } - - /// - /// Gets a System.UInt16 - /// - CorLibTypeSig UInt16 { get; } - - /// - /// Gets a System.Int32 - /// - CorLibTypeSig Int32 { get; } - - /// - /// Gets a System.UInt32 - /// - CorLibTypeSig UInt32 { get; } - - /// - /// Gets a System.Int64 - /// - CorLibTypeSig Int64 { get; } - - /// - /// Gets a System.UInt64 - /// - CorLibTypeSig UInt64 { get; } - - /// - /// Gets a System.Single - /// - CorLibTypeSig Single { get; } - - /// - /// Gets a System.Double - /// - CorLibTypeSig Double { get; } - - /// - /// Gets a System.String - /// - CorLibTypeSig String { get; } - - /// - /// Gets a System.TypedReference - /// - CorLibTypeSig TypedReference { get; } - - /// - /// Gets a System.IntPtr - /// - CorLibTypeSig IntPtr { get; } - - /// - /// Gets a System.UIntPtr - /// - CorLibTypeSig UIntPtr { get; } - - /// - /// Gets a System.Object - /// - CorLibTypeSig Object { get; } - - /// - /// Gets the assembly reference to the core library - /// - AssemblyRef AssemblyRef { get; } - - /// - /// Gets a that references a type in the core library assembly - /// - /// Namespace of type (eg. "System") - /// Name of type - /// A instance. This instance may be a cached instance. - TypeRef GetTypeRef(string @namespace, string name); - } - - public static partial class Extensions { - /// - /// Gets a if matches a primitive type. - /// - /// this - /// The type - /// A or null if it didn't match any primitive type - public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, ITypeDefOrRef type) { - CorLibTypeSig corLibType; - - if (type is TypeDef td && - td.DeclaringType 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 not null) { - return corLibType; - } - - return null; - } - - /// - /// Gets a if and - /// matches a primitive type. - /// - /// this - /// Namespace - /// 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) => - self.GetCorLibTypeSig(UTF8String.ToSystemStringOrEmpty(@namespace), UTF8String.ToSystemStringOrEmpty(name), defAsm); - - /// - /// Gets a if and - /// matches a primitive type. - /// - /// this - /// Namespace - /// Name - /// Definition assembly - /// A or null if it didn't match any primitive type - public static CorLibTypeSig GetCorLibTypeSig(this ICorLibTypes self, string @namespace, string name, IAssembly defAsm) { - if (@namespace != "System") - return null; - if (defAsm is null || !defAsm.IsCorLib()) - 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/Plugins/dnlib/DotNet/ICustomAttribute.cs b/Plugins/dnlib/DotNet/ICustomAttribute.cs deleted file mode 100644 index e80b4aa..0000000 --- a/Plugins/dnlib/DotNet/ICustomAttribute.cs +++ /dev/null @@ -1,41 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Custom attribute interface. Implemented by and - /// - /// - public interface ICustomAttribute { - /// - /// Gets the attribute type - /// - ITypeDefOrRef AttributeType { get; } - - /// - /// Gets the full name of the attribute type - /// - string TypeFullName { get; } - - /// - /// Gets all named arguments (field and property values) - /// - IList NamedArguments { get; } - - /// - /// true if is not empty - /// - bool HasNamedArguments { get; } - - /// - /// Gets all s that are field arguments - /// - IEnumerable Fields { get; } - - /// - /// Gets all s that are property arguments - /// - IEnumerable Properties { get; } - } -} diff --git a/Plugins/dnlib/DotNet/IDecrypters.cs b/Plugins/dnlib/DotNet/IDecrypters.cs deleted file mode 100644 index dc90367..0000000 --- a/Plugins/dnlib/DotNet/IDecrypters.cs +++ /dev/null @@ -1,37 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.PE; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet { - /// - /// Interface to decrypt methods - /// - public interface IMethodDecrypter { - /// - /// Gets the method's body - /// - /// Method rid - /// The found in the method's Method row - /// The method's parameters - /// Generic parameter context - /// Updated with the method's if this - /// method returns true - /// true if the method body was decrypted, false if the method isn't - /// encrypted and the default body reader code should be used. - bool GetMethodBody(uint rid, RVA rva, IList parameters, GenericParamContext gpContext, out MethodBody methodBody); - } - - /// - /// Interface to decrypt strings - /// - public interface IStringDecrypter { - /// - /// Reads a string - /// - /// String token - /// A string or null if we should read it from the #US heap - string ReadUserString(uint token); - } -} diff --git a/Plugins/dnlib/DotNet/ILogger.cs b/Plugins/dnlib/DotNet/ILogger.cs deleted file mode 100644 index 32952e4..0000000 --- a/Plugins/dnlib/DotNet/ILogger.cs +++ /dev/null @@ -1,435 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Reflection; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet { - /// - /// events - /// - public enum LoggerEvent { - /// - /// An error was detected. An exception should normally be thrown but the error - /// can be ignored. - /// - Error, - - /// - /// Just a warning and can be ignored. - /// - Warning, - - /// - /// A normal message - /// - Info, - - /// - /// A verbose message - /// - Verbose, - - /// - /// A very verbose message - /// - VeryVerbose, - } - - /// - /// Simple logger - /// - public interface ILogger { - /// - /// Log something - /// - /// Caller or null - /// Logger event - /// Format - /// Arguments - void Log(object sender, LoggerEvent loggerEvent, string format, params object[] args); - - /// - /// true if this event is ignored. If the event is ignored, the caller can - /// choose not to call . This is useful if it can take time to - /// prepare the message. - /// - /// The logger event - bool IgnoresEvent(LoggerEvent loggerEvent); - } - - public static partial class Extensions { - /// - /// Log an error message - /// - /// this - /// Sender or null - /// Message - public static void Error(this ILogger logger, object sender, string message) => - logger.Log(sender, LoggerEvent.Error, "{0}", message); - - /// - /// Log an error message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - public static void Error(this ILogger logger, object sender, string message, object arg1) => - logger.Log(sender, LoggerEvent.Error, message, arg1); - - /// - /// Log an error message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// Message arg #2 - 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 - /// - /// this - /// Sender or null - /// Message - /// 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) => - logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3); - - /// - /// Log an error message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// 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) => - logger.Log(sender, LoggerEvent.Error, message, arg1, arg2, arg3, arg4); - - /// - /// Log an error message - /// - /// this - /// Sender or null - /// Message - /// Message arguments - 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 - /// - /// this - /// Sender or null - /// Message - public static void Warning(this ILogger logger, object sender, string message) => - logger.Log(sender, LoggerEvent.Warning, "{0}", message); - - /// - /// Log a warning message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - public static void Warning(this ILogger logger, object sender, string message, object arg1) => - logger.Log(sender, LoggerEvent.Warning, message, arg1); - - /// - /// Log a warning message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// Message arg #2 - 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 - /// - /// this - /// Sender or null - /// Message - /// 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); - - /// - /// Log a warning message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// 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) => - logger.Log(sender, LoggerEvent.Warning, message, arg1, arg2, arg3, arg4); - - /// - /// Log a warning message - /// - /// this - /// Sender or null - /// Message - /// Message arguments - 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 - /// - /// this - /// Sender or null - /// Message - public static void Info(this ILogger logger, object sender, string message) => - logger.Log(sender, LoggerEvent.Info, "{0}", message); - - /// - /// Log an info message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - public static void Info(this ILogger logger, object sender, string message, object arg1) => - logger.Log(sender, LoggerEvent.Info, message, arg1); - - /// - /// Log an info message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// Message arg #2 - 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 - /// - /// this - /// Sender or null - /// Message - /// 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) => - logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3); - - /// - /// Log an info message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// 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) => - logger.Log(sender, LoggerEvent.Info, message, arg1, arg2, arg3, arg4); - - /// - /// Log an info message - /// - /// this - /// Sender or null - /// Message - /// Message arguments - 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 - /// - /// this - /// Sender or null - /// Message - public static void Verbose(this ILogger logger, object sender, string message) => - logger.Log(sender, LoggerEvent.Verbose, "{0}", message); - - /// - /// Log a verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - public static void Verbose(this ILogger logger, object sender, string message, object arg1) => - logger.Log(sender, LoggerEvent.Verbose, message, arg1); - - /// - /// Log a verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// Message arg #2 - 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 - /// - /// this - /// Sender or null - /// Message - /// 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) => - logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3); - - /// - /// Log a verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// 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) => - logger.Log(sender, LoggerEvent.Verbose, message, arg1, arg2, arg3, arg4); - - /// - /// Log a verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arguments - 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 - /// - /// this - /// Sender or null - /// Message - public static void VeryVerbose(this ILogger logger, object sender, string message) => - logger.Log(sender, LoggerEvent.VeryVerbose, "{0}", message); - - /// - /// Log a very verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - 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 - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// Message arg #2 - 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 - /// - /// this - /// Sender or null - /// Message - /// 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) => - logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3); - - /// - /// Log a very verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arg #1 - /// 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) => - logger.Log(sender, LoggerEvent.VeryVerbose, message, arg1, arg2, arg3, arg4); - - /// - /// Log a very verbose message - /// - /// this - /// Sender or null - /// Message - /// Message arguments - public static void VeryVerbose(this ILogger logger, object sender, string message, params object[] args) => - logger.Log(sender, LoggerEvent.VeryVerbose, message, args); - } - - /// - /// Dummy logger which ignores all messages, but can optionally throw on errors. - /// - public sealed class DummyLogger : ILogger { - ConstructorInfo ctor; - - /// - /// It ignores everything and doesn't throw anything. - /// - public static readonly DummyLogger NoThrowInstance = new DummyLogger(); - - /// - /// Throws a on errors, but ignores anything else. - /// - public static readonly DummyLogger ThrowModuleWriterExceptionOnErrorInstance = new DummyLogger(typeof(ModuleWriterException)); - - DummyLogger() { - } - - /// - /// Constructor - /// - /// If non-null, this exception type is thrown on - /// errors. It must have a public constructor that takes a as the only - /// argument. - public DummyLogger(Type exceptionToThrow) { - 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) }); - 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 is not null) - throw (Exception)ctor.Invoke(new object[] { string.Format(format, args) }); - } - - /// - public bool IgnoresEvent(LoggerEvent loggerEvent) { - if (ctor is null) - return true; - return loggerEvent != LoggerEvent.Error; - } - } -} diff --git a/Plugins/dnlib/DotNet/IResolver.cs b/Plugins/dnlib/DotNet/IResolver.cs deleted file mode 100644 index 136e2dc..0000000 --- a/Plugins/dnlib/DotNet/IResolver.cs +++ /dev/null @@ -1,125 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Resolves types, methods, fields - /// - public interface IResolver : ITypeResolver, IMemberRefResolver { - } - - /// - /// Resolves types - /// - public interface ITypeResolver { - /// - /// Resolves a type - /// - /// The type - /// The module that needs to resolve the type or null - /// A instance or null if it couldn't be resolved - TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule); - } - - /// - /// Resolves fields and methods - /// - public interface IMemberRefResolver { - /// - /// Resolves a method or a field - /// - /// A method/field reference - /// A or a instance or null - /// if it couldn't be resolved. - IMemberForwarded Resolve(MemberRef memberRef); - } - - public static partial class Extensions { - /// - /// Resolves a type - /// - /// this - /// The type - /// A instance or null if it couldn't be resolved - public static TypeDef Resolve(this ITypeResolver self, TypeRef typeRef) => self.Resolve(typeRef, null); - - /// - /// Resolves a type - /// - /// this - /// The type - /// A instance - /// If the type couldn't be resolved - public static TypeDef ResolveThrow(this ITypeResolver self, TypeRef typeRef) => self.ResolveThrow(typeRef, null); - - /// - /// Resolves a type - /// - /// this - /// The type - /// The module that needs to resolve the type or null - /// A instance - /// 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 not null) - return type; - throw new TypeResolveException($"Could not resolve type: {typeRef} ({typeRef?.DefinitionAssembly})"); - } - - /// - /// Resolves a method or a field - /// - /// this - /// A method/field reference - /// A or a instance - /// 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 not null) - return memberDef; - throw new MemberRefResolveException($"Could not resolve method/field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); - } - - /// - /// Resolves a field - /// - /// this - /// A field reference - /// A instance or null if it couldn't be resolved. - public static FieldDef ResolveField(this IMemberRefResolver self, MemberRef memberRef) => self.Resolve(memberRef) as FieldDef; - - /// - /// Resolves a field - /// - /// this - /// A field reference - /// 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) { - if (self.Resolve(memberRef) is FieldDef field) - return field; - throw new MemberRefResolveException($"Could not resolve field: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); - } - - /// - /// Resolves a method - /// - /// this - /// A method reference - /// A instance or null if it couldn't be resolved. - public static MethodDef ResolveMethod(this IMemberRefResolver self, MemberRef memberRef) => self.Resolve(memberRef) as MethodDef; - - /// - /// Resolves a method - /// - /// this - /// A method reference - /// 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) { - if (self.Resolve(memberRef) is MethodDef method) - return method; - throw new MemberRefResolveException($"Could not resolve method: {memberRef} ({memberRef?.GetDefinitionAssembly()})"); - } - } -} diff --git a/Plugins/dnlib/DotNet/ITokenResolver.cs b/Plugins/dnlib/DotNet/ITokenResolver.cs deleted file mode 100644 index 495aaa3..0000000 --- a/Plugins/dnlib/DotNet/ITokenResolver.cs +++ /dev/null @@ -1,26 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Resolves tokens - /// - public interface ITokenResolver { - /// - /// Resolves a token - /// - /// The metadata token - /// Generic parameter context - /// A or null if is invalid - IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext); - } - - public static partial class Extensions { - /// - /// Resolves a token - /// - /// This - /// The metadata token - /// A or null if is invalid - public static IMDTokenProvider ResolveToken(this ITokenResolver self, uint token) => self.ResolveToken(token, new GenericParamContext()); - } -} diff --git a/Plugins/dnlib/DotNet/IType.cs b/Plugins/dnlib/DotNet/IType.cs deleted file mode 100644 index 7a1dda7..0000000 --- a/Plugins/dnlib/DotNet/IType.cs +++ /dev/null @@ -1,110 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Interface to get the full name of a type - /// - public interface IType : IFullName, IOwnerModule, ICodedToken, IGenericParameterProvider, IContainsGenericParameter { - /// - /// true if it's a value type - /// - bool IsValueType { get; } - - /// - /// Returns the name of this type - /// - string TypeName { get; } - - /// - /// Returns the reflection name of this type - /// - string ReflectionName { get; } - - /// - /// Returns the namespace of this type - /// - string Namespace { get; } - - /// - /// Returns the reflection namespace of this type - /// - string ReflectionNamespace { get; } - - /// - /// Returns the reflection name of this type. See also . - /// - string ReflectionFullName { get; } - - /// - /// Returns the reflection name of this type, and includes the assembly name where the - /// type is located. It can be passed to to - /// load the type. - /// - string AssemblyQualifiedName { get; } - - /// - /// Gets the assembly where this type is defined - /// - IAssembly DefinitionAssembly { get; } - - /// - /// Gets the scope, which is different from since it - /// can differentiate between modules within the same assembly. - /// - IScope Scope { get; } - - /// - /// Gets the type whose scope is returned by and whose assembly - /// is returned by . This is always a - /// , or null. It can also be a - /// nested . - /// For example, if this type is a System.String&, then this value is a System.String. - /// If it's a generic instance type (eg. List<int>), then the generic type is - /// returned (eg. List<T>). In other words, the first or - /// that is found (without searching generic arguments) is returned. - /// - ITypeDefOrRef ScopeType { get; } - - /// - /// true if it's an integer or a floating point type - /// - bool IsPrimitive { get; } - } - - /// - /// Implemented by types and calling convention signatures. - /// - public interface IContainsGenericParameter { - /// - /// true if this contains a or a . - /// - bool ContainsGenericParameter { get; } - } - interface IContainsGenericParameter2 { - bool ContainsGenericParameter { get; } - } - - public static partial class Extensions { - /// - /// Returns , but if it's a nested , - /// return the non-nested - /// - /// this - /// The scope type - public static ITypeDefOrRef GetNonNestedTypeRefScope(this IType type) { - if (type is null) - return null; - var scopeType = type.ScopeType; - var tr = scopeType as TypeRef; - if (tr is null) - return scopeType; - for (int i = 0; i < 100; i++) { - var dt = tr.ResolutionScope as TypeRef; - if (dt is null) - return tr; - tr = dt; - } - return tr; - } - } -} diff --git a/Plugins/dnlib/DotNet/ITypeDefFinder.cs b/Plugins/dnlib/DotNet/ITypeDefFinder.cs deleted file mode 100644 index ab0b69c..0000000 --- a/Plugins/dnlib/DotNet/ITypeDefFinder.cs +++ /dev/null @@ -1,140 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Finds s - /// - public interface ITypeDefFinder { - /// - /// Finds a - /// - /// Full name of the type (no assembly information) - /// true if it's a reflection name, and nested - /// 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. - TypeDef Find(string fullName, bool isReflectionName); - - /// - /// Finds a . 's scope (i.e., module or - /// assembly) is ignored when looking up the type. - /// - /// The type ref - /// An existing or null if it wasn't found. - TypeDef Find(TypeRef typeRef); - } - - public static partial class Extensions { - /// - /// Finds a . Its scope (i.e., module or assembly) is ignored when - /// looking up the type. - /// - /// this - /// The type ref - /// An existing or null if it wasn't found. - /// If type couldn't be found - public static TypeDef FindThrow(this ITypeDefFinder self, TypeRef typeRef) { - var type = self.Find(typeRef); - if (type is not null) - return type; - throw new TypeResolveException($"Could not find type: {typeRef}"); - } - - /// - /// Finds a - /// - /// this - /// Full name of the type (no assembly information) - /// true if it's a reflection name, and nested - /// type names are separated by a + character. If false, nested type names - /// are separated by a / character. - /// An existing - /// 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 not null) - return type; - throw new TypeResolveException($"Could not find type: {fullName}"); - } - - /// - /// Finds a - /// - /// 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) => self.Find(fullName, false); - - /// - /// Finds a - /// - /// this - /// Full name of the type (no assembly information). Nested types are separated by / - /// An existing - /// If type couldn't be found - public static TypeDef FindNormalThrow(this ITypeDefFinder self, string fullName) { - var type = self.Find(fullName, false); - if (type is not null) - return type; - throw new TypeResolveException($"Could not find type: {fullName}"); - } - - /// - /// Finds a - /// - /// 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) => self.Find(fullName, true); - - /// - /// Finds a - /// - /// this - /// Full name of the type (no assembly information). Nested types are separated by + - /// An existing - /// If type couldn't be found - public static TypeDef FindReflectionThrow(this ITypeDefFinder self, string fullName) { - var type = self.Find(fullName, true); - if (type is not null) - return type; - throw new TypeResolveException($"Could not find type: {fullName}"); - } - - /// - /// Checks whether a exists. 's scope (i.e., - /// module or assembly) is ignored when looking up the type. - /// - /// this - /// The type ref - /// true if the exists, false otherwise - public static bool TypeExists(this ITypeDefFinder self, TypeRef typeRef) => self.Find(typeRef) is not null; - - /// - /// Checks whether a exists - /// - /// this - /// Full name of the type (no assembly information) - /// true if it's a reflection name, and nested - /// 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 not null; - - /// - /// Checks whether a exists - /// - /// 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 not null; - - /// - /// Checks whether a exists - /// - /// 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 not null; - } -} diff --git a/Plugins/dnlib/DotNet/IVariable.cs b/Plugins/dnlib/DotNet/IVariable.cs deleted file mode 100644 index 0cb4fb1..0000000 --- a/Plugins/dnlib/DotNet/IVariable.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Interface to access a local or a parameter - /// - public interface IVariable { - /// - /// Gets the variable type - /// - TypeSig Type { get; } - - /// - /// Gets the 0-based position - /// - int Index { get; } - - /// - /// Gets/sets the variable name - /// - string Name { get; set; } - } -} diff --git a/Plugins/dnlib/DotNet/ImplMap.cs b/Plugins/dnlib/DotNet/ImplMap.cs deleted file mode 100644 index 480ec7a..0000000 --- a/Plugins/dnlib/DotNet/ImplMap.cs +++ /dev/null @@ -1,301 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the ImplMap table - /// - [DebuggerDisplay("{Module} {Name}")] - public abstract class ImplMap : IMDTokenProvider { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.ImplMap, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - /// From column ImplMap.MappingFlags - /// - public PInvokeAttributes Attributes { - get => (PInvokeAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column ImplMap.ImportName - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column ImplMap.ImportScope - /// - public ModuleRef Module { - get => module; - set => module = value; - } - /// - protected ModuleRef module; - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(PInvokeAttributes andMask, PInvokeAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, PInvokeAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool IsNoMangle { - get => ((PInvokeAttributes)attributes & PInvokeAttributes.NoMangle) != 0; - set => ModifyAttributes(value, PInvokeAttributes.NoMangle); - } - - /// - /// Gets/sets the char set - /// - public PInvokeAttributes CharSet { - get => (PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask; - set => ModifyAttributes(~PInvokeAttributes.CharSetMask, value & PInvokeAttributes.CharSetMask); - } - - /// - /// true if is set - /// - public bool IsCharSetNotSpec => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetNotSpec; - - /// - /// true if is set - /// - public bool IsCharSetAnsi => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAnsi; - - /// - /// true if is set - /// - public bool IsCharSetUnicode => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetUnicode; - - /// - /// true if is set - /// - public bool IsCharSetAuto => ((PInvokeAttributes)attributes & PInvokeAttributes.CharSetMask) == PInvokeAttributes.CharSetAuto; - - /// - /// Gets/sets best fit - /// - public PInvokeAttributes BestFit { - get => (PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask; - set => ModifyAttributes(~PInvokeAttributes.BestFitMask, value & PInvokeAttributes.BestFitMask); - } - - /// - /// true if is set - /// - public bool IsBestFitUseAssem => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitUseAssem; - - /// - /// true if is set - /// - public bool IsBestFitEnabled => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitEnabled; - - /// - /// true if is set - /// - public bool IsBestFitDisabled => ((PInvokeAttributes)attributes & PInvokeAttributes.BestFitMask) == PInvokeAttributes.BestFitDisabled; - - /// - /// Gets/sets throw on unmappable char - /// - public PInvokeAttributes ThrowOnUnmappableChar { - get => (PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask; - set => ModifyAttributes(~PInvokeAttributes.ThrowOnUnmappableCharMask, value & PInvokeAttributes.ThrowOnUnmappableCharMask); - } - - /// - /// true if is set - /// - public bool IsThrowOnUnmappableCharUseAssem => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharUseAssem; - - /// - /// true if is set - /// - public bool IsThrowOnUnmappableCharEnabled => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharEnabled; - - /// - /// true if is set - /// - public bool IsThrowOnUnmappableCharDisabled => ((PInvokeAttributes)attributes & PInvokeAttributes.ThrowOnUnmappableCharMask) == PInvokeAttributes.ThrowOnUnmappableCharDisabled; - - /// - /// Gets/sets the bit - /// - public bool SupportsLastError { - get => ((PInvokeAttributes)attributes & PInvokeAttributes.SupportsLastError) != 0; - set => ModifyAttributes(value, PInvokeAttributes.SupportsLastError); - } - - /// - /// Gets/sets calling convention - /// - public PInvokeAttributes CallConv { - get => (PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask; - set => ModifyAttributes(~PInvokeAttributes.CallConvMask, value & PInvokeAttributes.CallConvMask); - } - - /// - /// true if is set - /// - public bool IsCallConvWinapi => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvWinapi; - - /// - /// true if is set - /// - public bool IsCallConvCdecl => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvCdecl; - - /// - /// true if is set - /// - public bool IsCallConvStdcall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvStdcall; - - /// - /// true if is set - /// - public bool IsCallConvThiscall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvThiscall; - - /// - /// true if is set - /// - public bool IsCallConvFastcall => ((PInvokeAttributes)attributes & PInvokeAttributes.CallConvMask) == PInvokeAttributes.CallConvFastcall; - - /// - /// Checks whether this is a certain P/Invoke method - /// - /// 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) => 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, treatAsWindows).Equals(GetDllName(mod.Name, treatAsWindows), StringComparison.OrdinalIgnoreCase); - } - - 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 || NETCOREAPP - RuntimeInformation.IsOSPlatform(OSPlatform.Windows); -#else - Path.DirectorySeparatorChar == '\\' || Path.AltDirectorySeparatorChar == '\\'; -#endif - - static readonly char[] trimChars = { ' ' }; - } - - /// - /// An ImplMap row created by the user and not present in the original .NET file - /// - public class ImplMapUser : ImplMap { - /// - /// Default constructor - /// - public ImplMapUser() { - } - - /// - /// Constructor - /// - /// Scope - /// Name - /// Flags - public ImplMapUser(ModuleRef scope, UTF8String name, PInvokeAttributes flags) { - module = scope; - this.name = name; - attributes = (int)flags; - } - } - - /// - /// Created from a row in the ImplMap table - /// - sealed class ImplMapMD : ImplMap, IMDTokenProviderMD { - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - /// Constructor - /// - /// The module which contains this ImplMap row - /// Row ID - /// If is null - /// If is invalid - public ImplMapMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ImplMapTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"ImplMap rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - bool b = readerModule.TablesStream.TryReadImplMapRow(origRid, out var row); - Debug.Assert(b); - attributes = row.MappingFlags; - name = readerModule.StringsStream.ReadNoNull(row.ImportName); - module = readerModule.ResolveModuleRef(row.ImportScope); - } - } -} diff --git a/Plugins/dnlib/DotNet/Importer.cs b/Plugins/dnlib/DotNet/Importer.cs deleted file mode 100644 index de37e66..0000000 --- a/Plugins/dnlib/DotNet/Importer.cs +++ /dev/null @@ -1,1194 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace dnlib.DotNet { - /// - /// options - /// - [Flags] - public enum ImporterOptions { - /// - /// Use s whenever possible if the is located - /// in this module. - /// - TryToUseTypeDefs = 1, - - /// - /// Use s whenever possible if the is located - /// in this module. - /// - TryToUseMethodDefs = 2, - - /// - /// Use s whenever possible if the is located - /// in this module. - /// - TryToUseFieldDefs = 4, - - /// - /// Use s, s and s - /// whenever possible if the definition is located in this module. - /// - /// - /// - /// - TryToUseDefs = TryToUseTypeDefs | TryToUseMethodDefs | TryToUseFieldDefs, - - /// - /// Use already existing s whenever possible - /// - TryToUseExistingAssemblyRefs = 8, - - /// - /// Don't set this flag. For internal use only. - /// - 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; - - /// - /// 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 ITypeDefOrRef Map(Type source) => null; - } - - /// - /// Imports s, s, s - /// and s as references - /// - public struct Importer { - readonly ModuleDef module; - internal readonly GenericParamContext gpContext; - readonly ImportMapper mapper; - RecursionCounter recursionCounter; - ImporterOptions options; - - 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; - set { - if (value) - options |= ImporterOptions.FixSignature; - else - options &= ~ImporterOptions.FixSignature; - } - } - - /// - /// Constructor - /// - /// The module that will own all references - public Importer(ModuleDef module) - : this(module, 0, new GenericParamContext(), null) { - } - - /// - /// Constructor - /// - /// The module that will own all references - /// Generic parameter context - public Importer(ModuleDef module, GenericParamContext gpContext) - : this(module, 0, gpContext, null) { - } - - /// - /// Constructor - /// - /// The module that will own all references - /// Importer options - public Importer(ModuleDef module, ImporterOptions options) - : 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, gpContext, null) { - } - - /// - /// Constructor - /// - /// The module that will own all references - /// Importer options - /// Generic parameter context - /// 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; - } - - /// - /// 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 . See also - /// - /// The type - /// - [Obsolete("Use 'Import(Type)' instead.")] - public ITypeDefOrRef ImportDeclaringType(Type type) => Import(type); - - /// - /// Imports a as a - /// - /// The 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) => - 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) => ImportAsTypeSig(type, null, false); - - TypeSig ImportAsTypeSig(Type type, Type declaringType, bool? treatAsGenericInst = null) { - if (type is null) - return null; - 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; - case ElementType.I1: return module.CorLibTypes.SByte; - case ElementType.U1: return module.CorLibTypes.Byte; - case ElementType.I2: return module.CorLibTypes.Int16; - case ElementType.U2: return module.CorLibTypes.UInt16; - case ElementType.I4: return module.CorLibTypes.Int32; - case ElementType.U4: return module.CorLibTypes.UInt32; - case ElementType.I8: return module.CorLibTypes.Int64; - case ElementType.U8: return module.CorLibTypes.UInt64; - case ElementType.R4: return module.CorLibTypes.Single; - case ElementType.R8: return module.CorLibTypes.Double; - case ElementType.String: return module.CorLibTypes.String; - 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(), 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(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); - - case ElementType.I: - FixSignature = true; // FnPtr is mapped to System.IntPtr - return module.CorLibTypes.IntPtr; - - case ElementType.Array: - // 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(), declaringType), (uint)type.GetArrayRank(), sizes, lowerBounds); - - case ElementType.GenericInst: - var typeGenArgs = type.GetGenericArguments(); - var git = new GenericInstSig(ImportAsTypeSig(type.GetGenericTypeDefinition(), null, false) as ClassOrValueTypeSig, (uint)typeGenArgs.Length); - foreach (var ga in typeGenArgs) - git.GenericArguments.Add(ImportAsTypeSig(ga, declaringType)); - return git; - - case ElementType.Sentinel: - case ElementType.Pinned: - case ElementType.FnPtr: // mapped to System.IntPtr - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.ValueArray: - case ElementType.R: - case ElementType.Internal: - case ElementType.Module: - case ElementType.End: - default: - return null; - } - } - - ITypeDefOrRef TryResolve(TypeRef tr) { - if (!TryToUseTypeDefs || tr is null) - return tr; - if (!IsThisModule(tr)) - return tr; - var td = tr.Resolve(); - if (td is null || td.Module != module) - return tr; - return td; - } - - IMethodDefOrRef TryResolveMethod(IMethodDefOrRef mdr) { - if (!TryToUseMethodDefs || mdr is null) - return mdr; - - var mr = mdr as MemberRef; - if (mr is null) - return mdr; - if (!mr.IsMethodRef) - return mr; - - var declType = GetDeclaringType(mr); - if (declType is null) - return mr; - if (declType.Module != module) - return mr; - return (IMethodDefOrRef)declType.ResolveMethod(mr) ?? mr; - } - - IField TryResolveField(MemberRef mr) { - if (!TryToUseFieldDefs || mr is null) - return mr; - - if (!mr.IsFieldRef) - return mr; - - var declType = GetDeclaringType(mr); - if (declType is null) - return mr; - if (declType.Module != module) - return mr; - return (IField)declType.ResolveField(mr) ?? mr; - } - - TypeDef GetDeclaringType(MemberRef mr) { - if (mr is null) - return null; - - if (mr.Class is TypeDef td) - return td; - - td = TryResolve(mr.Class as TypeRef) as TypeDef; - if (td is not null) - return td; - - var modRef = mr.Class as ModuleRef; - if (IsThisModule(modRef)) - return module.GlobalType; - - return null; - } - - bool IsThisModule(TypeRef tr) { - if (tr is null) - return false; - var scopeType = tr.GetNonNestedTypeRefScope() as TypeRef; - if (scopeType is null) - return false; - - if (module == scopeType.ResolutionScope) - return true; - - if (scopeType.ResolutionScope is ModuleRef modRef) - return IsThisModule(modRef); - - var asmRef = scopeType.ResolutionScope as AssemblyRef; - return Equals(module.Assembly, asmRef); - } - - bool IsThisModule(ModuleRef modRef) => - modRef is not null && - module.Name == modRef.Name && - Equals(module.Assembly, modRef.DefinitionAssembly); - - static bool Equals(IAssembly a, IAssembly b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - return Utils.Equals(a.Version, b.Version) && - PublicKeyBase.TokenEquals(a.PublicKeyOrToken, b.PublicKeyOrToken) && - UTF8String.Equals(a.Name, b.Name) && - UTF8String.CaseInsensitiveEquals(a.Culture, b.Culture); - } - - 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 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, CreateTypeRef(type.DeclaringType))); - } - - IResolutionScope CreateScopeReference(Type type) { - if (type is null) - return null; - var asmName = type.Assembly.GetName(); - var modAsm = module.Assembly; - 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; - return module.UpdateRowId(new ModuleRefUser(module, type.Module.ScopeName)); - } - } - 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 ?? string.Empty)); - } - - /// - /// Imports a as a - /// - /// The 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) => - ImportAsTypeSig(type, requiredModifiers, optionalModifiers, null); - - TypeSig ImportAsTypeSig(Type type, IList requiredModifiers, IList optionalModifiers, Type declaringType) { - if (type is null) - return null; - if (IsEmpty(requiredModifiers) && IsEmpty(optionalModifiers)) - return ImportAsTypeSig(type, declaringType); - - FixSignature = true; // Order of modifiers is unknown - 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. - // Assume all modifiers should be applied in the same order as in the lists. - - if (requiredModifiers is not null) { - foreach (var modifier in requiredModifiers) - ts = new CModReqdSig(Import(modifier), ts); - } - - if (optionalModifiers is not null) { - foreach (var modifier in optionalModifiers) - ts = new CModOptSig(Import(modifier), ts); - } - - return ts; - } - - static bool IsEmpty(IList list) => list is null || list.Count == 0; - - /// - /// Imports a as a . This will be either - /// a or a . - /// - /// The method - /// The imported method or null if is invalid - /// or if we failed to import the method - public IMethod Import(MethodBase methodBase) => Import(methodBase, false); - - /// - /// Imports a as a . This will be either - /// a or a . - /// - /// The method - /// Always verify method signature to make sure the - /// returned reference matches the metadata in the source assembly - /// The imported method or null if is invalid - /// or if we failed to import the method - public IMethod Import(MethodBase methodBase, bool forceFixSignature) { - FixSignature = false; - return ImportInternal(methodBase, forceFixSignature); - } - - IMethod ImportInternal(MethodBase methodBase) => ImportInternal(methodBase, false); - - 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: - } - - bool isMethodSpec = methodBase.IsGenericButNotGenericMethodDefinition(); - if (isMethodSpec) { - 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))); - 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)); - if (FixSignature && !forceFixSignature) { - //TODO: - } - return methodSpec; - } - else { - IMemberRefParent parent; - 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 is null) - return null; - - MethodBase origMethod; - try { - // Get the original method def in case the declaring type is a generic - // type instance and the method uses at least one generic type parameter. - origMethod = methodBase.Module.ResolveMethod(methodBase.MetadataToken); - } - catch (ArgumentException) { - // Here if eg. the method was created by the runtime (eg. a multi-dimensional - // array getter/setter method). The method token is in that case 0x06000000, - // which is invalid. - origMethod = methodBase; - } - - var methodSig = CreateMethodSig(origMethod); - IMethodDefOrRef methodRef = module.UpdateRowId(new MemberRefUser(module, methodBase.Name, methodSig, parent)); - methodRef = TryResolveMethod(methodRef); - if (FixSignature && !forceFixSignature) { - //TODO: - } - return methodRef; - } - } - - 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)); - - if (mb is MethodInfo mi) - sig.RetType = ImportAsTypeSig(mi.ReturnParameter, mb.DeclaringType); - else - sig.RetType = module.CorLibTypes.Void; - - foreach (var p in mb.GetParameters()) - sig.Params.Add(ImportAsTypeSig(p, mb.DeclaringType)); - - if (mb.IsGenericMethodDefinition) - sig.GenParamCount = (uint)mb.GetGenericArguments().Length; - - return sig; - } - - TypeSig ImportAsTypeSig(ParameterInfo p, Type declaringType) => - ImportAsTypeSig(p.ParameterType, p.GetRequiredCustomModifiers(), p.GetOptionalCustomModifiers(), declaringType); - - CallingConvention GetCallingConvention(MethodBase mb) { - CallingConvention cc = 0; - - var mbcc = mb.CallingConvention; - if (mb.IsGenericMethodDefinition) - cc |= CallingConvention.Generic; - if ((mbcc & CallingConventions.HasThis) != 0) - cc |= CallingConvention.HasThis; - if ((mbcc & CallingConventions.ExplicitThis) != 0) - cc |= CallingConvention.ExplicitThis; - - switch (mbcc & CallingConventions.Any) { - case CallingConventions.Standard: - cc |= CallingConvention.Default; - break; - - case CallingConventions.VarArgs: - cc |= CallingConvention.VarArg; - break; - - case CallingConventions.Any: - default: - FixSignature = true; - cc |= CallingConvention.Default; - break; - } - - return cc; - } - - GenericInstMethodSig CreateGenericInstMethodSig(MethodBase mb) { - var genMethodArgs = mb.GetGenericArguments(); - var gim = new GenericInstMethodSig(CallingConvention.GenericInst, (uint)genMethodArgs.Length); - foreach (var gma in genMethodArgs) - gim.GenericArguments.Add(ImportAsTypeSig(gma)); - return gim; - } - - IMemberRefParent GetModuleParent(Module module2) { - 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 - /// - /// The field - /// The imported field or null if is invalid - /// or if we failed to import the field - public IField Import(FieldInfo fieldInfo) => Import(fieldInfo, false); - - /// - /// Imports a as a - /// - /// The field - /// Always verify field signature to make sure the - /// returned reference matches the metadata in the source assembly - /// The imported field or null if is invalid - /// or if we failed to import the field - public IField Import(FieldInfo fieldInfo, bool forceFixSignature) { - FixSignature = false; - 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: - } - - IMemberRefParent parent; - 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 is null) - return null; - - FieldInfo origField; - try { - // Get the original field def in case the declaring type is a generic - // type instance and the field uses a generic type parameter. - origField = fieldInfo.Module.ResolveField(fieldInfo.MetadataToken); - } - catch (ArgumentException) { - origField = fieldInfo; - } - - 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); - if (FixSignature && !forceFixSignature) { - //TODO: - } - return field; - } - - /// - /// Imports a - /// - /// The type - /// The imported type or null - public IType Import(IType type) { - if (type is null) - return null; - if (!recursionCounter.Increment()) - return null; - - IType result; - TypeDef td; - TypeRef tr; - TypeSpec ts; - TypeSig sig; - - if ((td = type as TypeDef) is not null) - result = Import(td); - else if ((tr = type as TypeRef) is not null) - result = Import(tr); - else if ((ts = type as TypeSpec) is not null) - result = Import(ts); - else if ((sig = type as TypeSig) is not null) - result = Import(sig); - else - result = null; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a as a - /// - /// The type - /// The imported type or null - public ITypeDefOrRef Import(TypeDef type) { - if (type is null) - return null; - if (TryToUseTypeDefs && type.Module == module) - return type; - var mapped = mapper?.Map(type); - if (mapped is not null) - return mapped; - return Import2(type); - } - - TypeRef Import2(TypeDef type) { - if (type is null) - return null; - if (!recursionCounter.Increment()) - return null; - TypeRef result; - - var declType = type.DeclaringType; - 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))); - - recursionCounter.Decrement(); - return result; - } - - IResolutionScope CreateScopeReference(IAssembly defAsm, ModuleDef defMod) { - if (defAsm is null) - return null; - var modAsm = module.Assembly; - 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; - return module.UpdateRowId(new ModuleRefUser(module, defMod.Name)); - } - } - 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 }); - } - - /// - /// Imports a - /// - /// The type - /// The imported type or null - public ITypeDefOrRef Import(TypeRef type) { - var mapped = mapper?.Map(type); - if (mapped is not null) - return mapped; - - return TryResolve(Import2(type)); - } - - TypeRef Import2(TypeRef type) { - if (type is null) - return null; - if (!recursionCounter.Increment()) - return null; - TypeRef result; - - var declaringType = type.DeclaringType; - 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))); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The type - /// The imported type or null - public TypeSpec Import(TypeSpec type) { - if (type is null) - return null; - return module.UpdateRowId(new TypeSpecUser(Import(type.TypeSig))); - } - - /// - /// Imports a - /// - /// The type - /// The imported type or null - public TypeSig Import(TypeSig type) { - if (type is null) - return null; - if (!recursionCounter.Increment()) - return null; - - TypeSig result; - switch (type.ElementType) { - case ElementType.Void: result = module.CorLibTypes.Void; break; - case ElementType.Boolean: result = module.CorLibTypes.Boolean; break; - case ElementType.Char: result = module.CorLibTypes.Char; break; - case ElementType.I1: result = module.CorLibTypes.SByte; break; - case ElementType.U1: result = module.CorLibTypes.Byte; break; - case ElementType.I2: result = module.CorLibTypes.Int16; break; - case ElementType.U2: result = module.CorLibTypes.UInt16; break; - case ElementType.I4: result = module.CorLibTypes.Int32; break; - case ElementType.U4: result = module.CorLibTypes.UInt32; break; - case ElementType.I8: result = module.CorLibTypes.Int64; break; - case ElementType.U8: result = module.CorLibTypes.UInt64; break; - case ElementType.R4: result = module.CorLibTypes.Single; break; - case ElementType.R8: result = module.CorLibTypes.Double; break; - case ElementType.String: result = module.CorLibTypes.String; break; - case ElementType.TypedByRef:result = module.CorLibTypes.TypedReference; break; - case ElementType.I: result = module.CorLibTypes.IntPtr; break; - case ElementType.U: result = module.CorLibTypes.UIntPtr; break; - case ElementType.Object: result = module.CorLibTypes.Object; break; - case ElementType.Ptr: result = new PtrSig(Import(type.Next)); break; - case ElementType.ByRef: result = new ByRefSig(Import(type.Next)); break; - case ElementType.ValueType: result = CreateClassOrValueType((type as ClassOrValueTypeSig).TypeDefOrRef, true); break; - case ElementType.Class: result = CreateClassOrValueType((type as ClassOrValueTypeSig).TypeDefOrRef, false); break; - case ElementType.Var: result = new GenericVar((type as GenericVar).Number, gpContext.Type); break; - case ElementType.ValueArray:result = new ValueArraySig(Import(type.Next), (type as ValueArraySig).Size); break; - case ElementType.FnPtr: result = new FnPtrSig(Import((type as FnPtrSig).Signature)); break; - case ElementType.SZArray: result = new SZArraySig(Import(type.Next)); break; - case ElementType.MVar: result = new GenericMVar((type as GenericMVar).Number, gpContext.Method); break; - case ElementType.CModReqd: result = new CModReqdSig(Import((type as ModifierSig).Modifier), Import(type.Next)); break; - case ElementType.CModOpt: result = new CModOptSig(Import((type as ModifierSig).Modifier), Import(type.Next)); break; - case ElementType.Module: result = new ModuleSig((type as ModuleSig).Index, Import(type.Next)); break; - case ElementType.Sentinel: result = new SentinelSig(); break; - case ElementType.Pinned: result = new PinnedSig(Import(type.Next)); break; - - case ElementType.Array: - var arraySig = (ArraySig)type; - var sizes = new List(arraySig.Sizes); - var lbounds = new List(arraySig.LowerBounds); - result = new ArraySig(Import(type.Next), arraySig.Rank, sizes, lbounds); - break; - - case ElementType.GenericInst: - var gis = (GenericInstSig)type; - var genArgs = new List(gis.GenericArguments.Count); - foreach (var ga in gis.GenericArguments) - genArgs.Add(Import(ga)); - result = new GenericInstSig(Import(gis.GenericType) as ClassOrValueTypeSig, genArgs); - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = null; - break; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// 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); - if (corLibType is not null) - return corLibType; - - if (isValueType) - return new ValueTypeSig(Import(type)); - return new ClassSig(Import(type)); - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public CallingConventionSig Import(CallingConventionSig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - CallingConventionSig result; - - var sigType = sig.GetType(); - if (sigType == typeof(MethodSig)) - result = Import((MethodSig)sig); - else if (sigType == typeof(FieldSig)) - result = Import((FieldSig)sig); - else if (sigType == typeof(GenericInstMethodSig)) - result = Import((GenericInstMethodSig)sig); - else if (sigType == typeof(PropertySig)) - result = Import((PropertySig)sig); - else if (sigType == typeof(LocalSig)) - result = Import((LocalSig)sig); - else - result = null; // Should never be reached - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public FieldSig Import(FieldSig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - - var result = new FieldSig(sig.GetCallingConvention(), Import(sig.Type)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public MethodSig Import(MethodSig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - - var result = Import(new MethodSig(sig.GetCallingConvention()), sig); - - recursionCounter.Decrement(); - return result; - } - - T Import(T sig, T old) where T : MethodBaseSig { - sig.RetType = Import(old.RetType); - foreach (var p in old.Params) - sig.Params.Add(Import(p)); - sig.GenParamCount = old.GenParamCount; - var paramsAfterSentinel = sig.ParamsAfterSentinel; - if (paramsAfterSentinel is not null) { - foreach (var p in old.ParamsAfterSentinel) - paramsAfterSentinel.Add(Import(p)); - } - return sig; - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public PropertySig Import(PropertySig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - - var result = Import(new PropertySig(sig.GetCallingConvention()), sig); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public LocalSig Import(LocalSig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - - var result = new LocalSig(sig.GetCallingConvention(), (uint)sig.Locals.Count); - foreach (var l in sig.Locals) - result.Locals.Add(Import(l)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The sig - /// The imported sig or null if input is invalid - public GenericInstMethodSig Import(GenericInstMethodSig sig) { - if (sig is null) - return null; - if (!recursionCounter.Increment()) - return null; - - var result = new GenericInstMethodSig(sig.GetCallingConvention(), (uint)sig.GenericArguments.Count); - foreach (var l in sig.GenericArguments) - result.GenericArguments.Add(Import(l)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The field - /// The imported type or null if is invalid - public IField Import(IField field) { - if (field is null) - return null; - if (!recursionCounter.Increment()) - return null; - - IField result; - MemberRef mr; - FieldDef fd; - - if ((fd = field as FieldDef) is not null) - result = Import(fd); - else if ((mr = field as MemberRef) is not null) - result = Import(mr); - else - result = null; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The method - /// The imported method or null if is invalid - public IMethod Import(IMethod method) { - if (method is null) - return null; - if (!recursionCounter.Increment()) - return null; - - IMethod result; - MethodDef md; - MethodSpec ms; - MemberRef mr; - - if ((md = method as MethodDef) is not null) - result = Import(md); - else if ((ms = method as MethodSpec) is not null) - result = Import(ms); - else if ((mr = method as MemberRef) is not null) - result = Import(mr); - else - result = null; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a as an - /// - /// The field - /// The imported type or null if is invalid - public IField Import(FieldDef field) { - 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 is not null) { - recursionCounter.Decrement(); - return mapped; - } - - MemberRef result = module.UpdateRowId(new MemberRefUser(module, field.Name)); - result.Signature = Import(field.Signature); - result.Class = ImportParent(field.DeclaringType); - - recursionCounter.Decrement(); - return result; - } - - IMemberRefParent ImportParent(TypeDef type) { - if (type is null) - return null; - if (type.IsGlobalModuleType) - return module.UpdateRowId(new ModuleRefUser(module, type.Module?.Name)); - return Import(type); - } - - /// - /// Imports a as an - /// - /// The method - /// The imported method or null if is invalid - public IMethod Import(MethodDef method) { - 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 is not null) { - recursionCounter.Decrement(); - return mapped; - } - - MemberRef result = module.UpdateRowId(new MemberRefUser(module, method.Name)); - result.Signature = Import(method.Signature); - result.Class = ImportParent(method.DeclaringType); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The method - /// The imported method or null if is invalid - public MethodSpec Import(MethodSpec method) { - if (method is null) - return null; - if (!recursionCounter.Increment()) - return null; - - MethodSpec result = module.UpdateRowId(new MethodSpecUser((IMethodDefOrRef)Import(method.Method))); - result.Instantiation = Import(method.Instantiation); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Imports a - /// - /// The member ref - /// The imported member ref or null if is invalid - public MemberRef Import(MemberRef memberRef) { - if (memberRef is null) - return null; - if (!recursionCounter.Increment()) - return null; - var mapped = mapper?.Map(memberRef); - if (mapped is not null) { - recursionCounter.Decrement(); - return mapped; - } - - MemberRef result = module.UpdateRowId(new MemberRefUser(module, memberRef.Name)); - result.Signature = Import(memberRef.Signature); - result.Class = Import(memberRef.Class); - if (result.Class is null) // Will be null if memberRef.Class is null or a MethodDef - result = null; - - recursionCounter.Decrement(); - return result; - } - - IMemberRefParent Import(IMemberRefParent parent) { - if (parent is ITypeDefOrRef tdr) { - if (tdr is TypeDef td && td.IsGlobalModuleType) - return module.UpdateRowId(new ModuleRefUser(module, td.Module?.Name)); - return Import(tdr); - } - - if (parent is ModuleRef modRef) - return module.UpdateRowId(new ModuleRefUser(module, modRef.Name)); - - if (parent is MethodDef method) { - var dt = method.DeclaringType; - return dt is null || dt.Module != module ? null : method; - } - - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/InterfaceImpl.cs b/Plugins/dnlib/DotNet/InterfaceImpl.cs deleted file mode 100644 index a326c7a..0000000 --- a/Plugins/dnlib/DotNet/InterfaceImpl.cs +++ /dev/null @@ -1,157 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the InterfaceImpl table - /// - [DebuggerDisplay("{Interface}")] - public abstract class InterfaceImpl : IHasCustomAttribute, IContainsGenericParameter, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.InterfaceImpl, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 5; - - /// - /// From column InterfaceImpl.Interface - /// - public ITypeDefOrRef Interface { - get => @interface; - set => @interface = value; - } - /// - protected ITypeDefOrRef @interface; - - /// - /// 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 => 5; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - } - - /// - /// An InterfaceImpl row created by the user and not present in the original .NET file - /// - public class InterfaceImplUser : InterfaceImpl { - /// - /// Default constructor - /// - public InterfaceImplUser() { - } - - /// - /// Constructor - /// - /// The interface the type implements - public InterfaceImplUser(ITypeDefOrRef @interface) => this.@interface = @interface; - } - - /// - /// Created from a row in the InterfaceImpl table - /// - sealed class InterfaceImplMD : InterfaceImpl, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - - /// - public uint OrigRid => origRid; - - bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.InterfaceImpl, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this InterfaceImpl row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public InterfaceImplMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.InterfaceImplTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"InterfaceImpl rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - bool b = readerModule.TablesStream.TryReadInterfaceImplRow(origRid, out var row); - Debug.Assert(b); - @interface = readerModule.ResolveTypeDefOrRef(row.Interface, gpContext); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/BlobStream.cs b/Plugins/dnlib/DotNet/MD/BlobStream.cs deleted file mode 100644 index 984ab0a..0000000 --- a/Plugins/dnlib/DotNet/MD/BlobStream.cs +++ /dev/null @@ -1,73 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Represents the #Blob stream - /// - public sealed class BlobStream : HeapStream { - /// - public BlobStream() { - } - - /// - public BlobStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - } - - /// - /// Reads data - /// - /// Offset of data - /// The data or null if invalid offset - public byte[] Read(uint offset) { - // The CLR has a special check for offset 0. It always interprets it as - // 0-length data, even if that first byte isn't 0 at all. - if (offset == 0) - return Array2.Empty(); - if (!TryCreateReader(offset, out var reader)) - return null; - return reader.ToArray(); - } - - /// - /// Reads data just like , but returns an empty array if - /// offset is invalid - /// - /// Offset of data - /// The data - public byte[] ReadNoNull(uint offset) => Read(offset) ?? Array2.Empty(); - - /// - /// Creates a reader that can access a blob - /// - /// Offset of blob - /// A new stream - public DataReader CreateReader(uint offset) { - if (TryCreateReader(offset, out var reader)) - return reader; - return default; - } - - /// - /// Creates a reader that can access a blob or returns false on failure - /// - /// Offset of blob - /// Updated with the reader - /// - public bool TryCreateReader(uint offset, out DataReader reader) { - reader = dataReader; - if (!IsValidOffset(offset)) - return false; - reader.Position = offset; - if (!reader.TryReadCompressedUInt32(out uint length)) - return false; - if (!reader.CanRead(length)) - return false; - reader = reader.Slice(reader.Position, length); - return true; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/CodedToken.cs b/Plugins/dnlib/DotNet/MD/CodedToken.cs deleted file mode 100644 index a77f4f4..0000000 --- a/Plugins/dnlib/DotNet/MD/CodedToken.cs +++ /dev/null @@ -1,214 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.MD { - /// - /// Contains all possible coded token classes - /// - public sealed class CodedToken { - /// TypeDefOrRef coded token - public static readonly CodedToken TypeDefOrRef = new CodedToken(2, new Table[3] { - Table.TypeDef, Table.TypeRef, Table.TypeSpec, - }); - - /// HasConstant coded token - public static readonly CodedToken HasConstant = new CodedToken(2, new Table[3] { - Table.Field, Table.Param, Table.Property, - }); - - /// HasCustomAttribute coded token - public static readonly CodedToken HasCustomAttribute = new CodedToken(5, new Table[24] { - 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, 0, 0, - }); - - /// HasFieldMarshal coded token - public static readonly CodedToken HasFieldMarshal = new CodedToken(1, new Table[2] { - Table.Field, Table.Param, - }); - - /// HasDeclSecurity coded token - public static readonly CodedToken HasDeclSecurity = new CodedToken(2, new Table[3] { - Table.TypeDef, Table.Method, Table.Assembly, - }); - - /// MemberRefParent coded token - public static readonly CodedToken MemberRefParent = new CodedToken(3, new Table[5] { - Table.TypeDef, Table.TypeRef, Table.ModuleRef, Table.Method, - Table.TypeSpec, - }); - - /// HasSemantic coded token - public static readonly CodedToken HasSemantic = new CodedToken(1, new Table[2] { - Table.Event, Table.Property, - }); - - /// MethodDefOrRef coded token - public static readonly CodedToken MethodDefOrRef = new CodedToken(1, new Table[2] { - Table.Method, Table.MemberRef, - }); - - /// MemberForwarded coded token - public static readonly CodedToken MemberForwarded = new CodedToken(1, new Table[2] { - Table.Field, Table.Method, - }); - - /// Implementation coded token - public static readonly CodedToken Implementation = new CodedToken(2, new Table[3] { - Table.File, Table.AssemblyRef, Table.ExportedType, - }); - - /// CustomAttributeType coded token - public static readonly CodedToken CustomAttributeType = new CodedToken(3, new Table[5] { - 0, 0, Table.Method, Table.MemberRef, 0, - }); - - /// ResolutionScope coded token - public static readonly CodedToken ResolutionScope = new CodedToken(2, new Table[4] { - Table.Module, Table.ModuleRef, Table.AssemblyRef, Table.TypeRef, - }); - - /// TypeOrMethodDef coded token - public static readonly CodedToken TypeOrMethodDef = new CodedToken(1, new Table[2] { - 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; - - /// - /// Returns all types of tables - /// - public Table[] TableTypes => tableTypes; - - /// - /// Returns the number of bits that is used to encode table type - /// - public int Bits => bits; - - /// - /// Constructor - /// - /// Number of bits used to encode token type - /// All table types - internal CodedToken(int bits, Table[] tableTypes) { - this.bits = bits; - mask = (1 << bits) - 1; - this.tableTypes = tableTypes; - } - - /// - /// Encodes a token - /// - /// The token - /// Coded token - /// - public uint Encode(MDToken token) => Encode(token.Raw); - - /// - /// Encodes a token - /// - /// The token - /// Coded token - /// - public uint Encode(uint token) { - Encode(token, out uint codedToken); - return codedToken; - } - - /// - /// Encodes a token - /// - /// The token - /// Coded token - /// true if successful - public bool Encode(MDToken token, out uint codedToken) => Encode(token.Raw, out codedToken); - - /// - /// Encodes a token - /// - /// The token - /// Coded token - /// true if successful - public bool Encode(uint token, out uint codedToken) { - int index = Array.IndexOf(tableTypes, MDToken.ToTable(token)); - if (index < 0) { - codedToken = uint.MaxValue; - return false; - } - // This shift can never overflow a uint since bits < 8 (it's at most 5), and - // ToRid() returns an integer <= 0x00FFFFFF. - codedToken = (MDToken.ToRID(token) << bits) | (uint)index; - return true; - } - - /// - /// Decodes a coded token - /// - /// The coded token - /// Decoded token or 0 on failure - /// - public MDToken Decode2(uint codedToken) { - Decode(codedToken, out uint token); - return new MDToken(token); - } - - /// - /// Decodes a coded token - /// - /// The coded token - /// Decoded token or 0 on failure - /// - public uint Decode(uint codedToken) { - Decode(codedToken, out uint token); - return token; - } - - /// - /// Decodes a coded token - /// - /// The coded token - /// Decoded token - /// true if successful - public bool Decode(uint codedToken, out MDToken token) { - bool result = Decode(codedToken, out uint decodedToken); - token = new MDToken(decodedToken); - return result; - } - - /// - /// Decodes a coded token - /// - /// The coded token - /// Decoded token - /// true if successful - public bool Decode(uint codedToken, out uint token) { - uint rid = codedToken >> bits; - int index = (int)(codedToken & mask); - if (rid > MDToken.RID_MAX || index >= tableTypes.Length) { - token = 0; - return false; - } - - token = ((uint)tableTypes[index] << MDToken.TABLE_SHIFT) | rid; - return true; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/ColumnInfo.cs b/Plugins/dnlib/DotNet/MD/ColumnInfo.cs deleted file mode 100644 index 02c7b6b..0000000 --- a/Plugins/dnlib/DotNet/MD/ColumnInfo.cs +++ /dev/null @@ -1,119 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.DotNet.Writer; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Info about one column in a MD table - /// - [DebuggerDisplay("{offset} {size} {name}")] - public sealed class ColumnInfo { - readonly byte index; - byte offset; - readonly ColumnSize columnSize; - byte size; - readonly string name; - - /// - /// Gets the column index - /// - public int Index => index; - - /// - /// Returns the column offset within the table row - /// - public int Offset { - get => offset; - internal set => offset = (byte)value; - } - - /// - /// Returns the column size - /// - public int Size { - get => size; - internal set => size = (byte)value; - } - - /// - /// Returns the column name - /// - public string Name => name; - - /// - /// Returns the ColumnSize enum value - /// - public ColumnSize ColumnSize => columnSize; - - /// - /// Constructor - /// - /// Column index - /// The column name - /// Column size - public ColumnInfo(byte index, string name, ColumnSize columnSize) { - this.index = index; - this.name = name; - this.columnSize = columnSize; - } - - /// - /// Constructor - /// - /// Column index - /// The column name - /// Column size - /// Offset of column - /// Size of column - public ColumnInfo(byte index, string name, ColumnSize columnSize, byte offset, byte size) { - this.index = index; - this.name = name; - this.columnSize = columnSize; - this.offset = offset; - this.size = size; - } - - /// - /// Reads the column - /// - /// A reader positioned on this column - /// The column value - 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); - return size == 2 ? reader.Unsafe_ReadUInt16() : reader.Unsafe_ReadUInt32(); - } - - /// - /// Writes a column - /// - /// The writer position on this column - /// The column value - public void Write(DataWriter writer, uint value) { - switch (size) { - 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"); - } - } - - internal void Write24(DataWriter writer, uint value) { - Debug.Assert(size == 2 || size == 4); - if (size == 2) - writer.WriteUInt16((ushort)value); - else - writer.WriteUInt32(value); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/ColumnSize.cs b/Plugins/dnlib/DotNet/MD/ColumnSize.cs deleted file mode 100644 index 7784c66..0000000 --- a/Plugins/dnlib/DotNet/MD/ColumnSize.cs +++ /dev/null @@ -1,159 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.MD { - /// - /// MD table column size - /// - public enum ColumnSize : byte { - /// RID into Module table - Module, - /// RID into TypeRef table - TypeRef, - /// RID into TypeDef table - TypeDef, - /// RID into FieldPtr table - FieldPtr, - /// RID into Field table - Field, - /// RID into MethodPtr table - MethodPtr, - /// RID into Method table - Method, - /// RID into ParamPtr table - ParamPtr, - /// RID into Param table - Param, - /// RID into InterfaceImpl table - InterfaceImpl, - /// RID into MemberRef table - MemberRef, - /// RID into Constant table - Constant, - /// RID into CustomAttribute table - CustomAttribute, - /// RID into FieldMarshal table - FieldMarshal, - /// RID into DeclSecurity table - DeclSecurity, - /// RID into ClassLayout table - ClassLayout, - /// RID into FieldLayout table - FieldLayout, - /// RID into StandAloneSig table - StandAloneSig, - /// RID into EventMap table - EventMap, - /// RID into EventPtr table - EventPtr, - /// RID into Event table - Event, - /// RID into PropertyMap table - PropertyMap, - /// RID into PropertyPtr table - PropertyPtr, - /// RID into Property table - Property, - /// RID into MethodSemantics table - MethodSemantics, - /// RID into MethodImpl table - MethodImpl, - /// RID into ModuleRef table - ModuleRef, - /// RID into TypeSpec table - TypeSpec, - /// RID into ImplMap table - ImplMap, - /// RID into FieldRVA table - FieldRVA, - /// RID into ENCLog table - ENCLog, - /// RID into ENCMap table - ENCMap, - /// RID into Assembly table - Assembly, - /// RID into AssemblyProcessor table - AssemblyProcessor, - /// RID into AssemblyOS table - AssemblyOS, - /// RID into AssemblyRef table - AssemblyRef, - /// RID into AssemblyRefProcessor table - AssemblyRefProcessor, - /// RID into AssemblyRefOS table - AssemblyRefOS, - /// RID into File table - File, - /// RID into ExportedType table - ExportedType, - /// RID into ManifestResource table - ManifestResource, - /// RID into NestedClass table - NestedClass, - /// RID into GenericParam table - GenericParam, - /// RID into MethodSpec table - 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 - Int16, - /// 16-bit unsigned int - UInt16, - /// 32-bit signed int - Int32, - /// 32-bit unsigned int - UInt32, - /// Index into #Strings stream - Strings, - /// Index into #GUID stream - GUID, - /// Index into #Blob stream - Blob, - /// TypeDefOrRef encoded token - TypeDefOrRef, - /// HasConstant encoded token - HasConstant, - /// HasCustomAttribute encoded token - HasCustomAttribute, - /// HasFieldMarshal encoded token - HasFieldMarshal, - /// HasDeclSecurity encoded token - HasDeclSecurity, - /// MemberRefParent encoded token - MemberRefParent, - /// HasSemantic encoded token - HasSemantic, - /// MethodDefOrRef encoded token - MethodDefOrRef, - /// MemberForwarded encoded token - MemberForwarded, - /// Implementation encoded token - Implementation, - /// CustomAttributeType encoded token - CustomAttributeType, - /// ResolutionScope encoded token - ResolutionScope, - /// TypeOrMethodDef encoded token - TypeOrMethodDef, - /// HasCustomDebugInformation encoded token - HasCustomDebugInformation, - } -} diff --git a/Plugins/dnlib/DotNet/MD/ComImageFlags.cs b/Plugins/dnlib/DotNet/MD/ComImageFlags.cs deleted file mode 100644 index 0ddef31..0000000 --- a/Plugins/dnlib/DotNet/MD/ComImageFlags.cs +++ /dev/null @@ -1,46 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.MD { - /// - /// See COMIMAGE_FLAGS_XXX in CorHdr.h in the Windows SDK - /// - [Flags] - public enum ComImageFlags : uint { - /// - /// See COMIMAGE_FLAGS_ILONLY in the Windows SDK - /// - ILOnly = 1, - - /// - /// See COMIMAGE_FLAGS_32BITREQUIRED in the Windows SDK - /// - Bit32Required = 2, - - /// - /// Set if a native header exists (COMIMAGE_FLAGS_IL_LIBRARY) - /// - ILLibrary = 4, - - /// - /// See COMIMAGE_FLAGS_STRONGNAMESIGNED in the Windows SDK - /// - StrongNameSigned = 8, - - /// - /// See COMIMAGE_FLAGS_NATIVE_ENTRYPOINT in the Windows SDK - /// - NativeEntryPoint = 0x10, - - /// - /// See COMIMAGE_FLAGS_TRACKDEBUGDATA in the Windows SDK - /// - TrackDebugData = 0x10000, - - /// - /// See COMIMAGE_FLAGS_32BITPREFERRED in the Windows SDK - /// - Bit32Preferred = 0x20000, - } -} diff --git a/Plugins/dnlib/DotNet/MD/CompressedMetadata.cs b/Plugins/dnlib/DotNet/MD/CompressedMetadata.cs deleted file mode 100644 index 6806205..0000000 --- a/Plugins/dnlib/DotNet/MD/CompressedMetadata.cs +++ /dev/null @@ -1,178 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -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, CLRRuntimeReaderKind runtime) - : base(peImage, cor20Header, mdHeader) { - this.runtime = runtime; - } - - /// - internal CompressedMetadata(MetadataHeader mdHeader, bool isStandalonePortablePdb, CLRRuntimeReaderKind runtime) - : base(mdHeader, isStandalonePortablePdb) { - this.runtime = runtime; - } - - /// - 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]; - 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); - newAllStreams.Add(pdbStream); - continue; - } - break; - - case "#JTD": - if (runtime == CLRRuntimeReaderKind.Mono) { - forceAllBig = true; - continue; - } - break; - } - dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); - newAllStreams.Add(dns); - dns = null; - } - } - finally { - dns?.Dispose(); - newAllStreams.Reverse(); - allStreams = newAllStreams; - } - - if (tablesStream is null) - throw new BadImageFormatException("Missing MD stream"); - - if (pdbStream is not null) - tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig); - else - tablesStream.Initialize(null, forceAllBig); - } - - /// - public override RidList GetFieldRidList(uint typeDefRid) => GetRidList(tablesStream.TypeDefTable, typeDefRid, 4, tablesStream.FieldTable); - - /// - public override RidList GetMethodRidList(uint typeDefRid) => GetRidList(tablesStream.TypeDefTable, typeDefRid, 5, tablesStream.MethodTable); - - /// - public override RidList GetParamRidList(uint methodRid) => GetRidList(tablesStream.MethodTable, methodRid, 5, tablesStream.ParamTable); - - /// - public override RidList GetEventRidList(uint eventMapRid) => GetRidList(tablesStream.EventMapTable, eventMapRid, 1, tablesStream.EventTable); - - /// - 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) - /// - /// Source table, eg. TypeDef - /// Row ID in - /// Column index in , eg. 4 for TypeDef.FieldList - /// Destination table, eg. Field - /// A new instance - RidList GetRidList(MDTable tableSource, uint tableSourceRid, int colIndex, MDTable tableDest) { - var column = tableSource.TableInfo.Columns[colIndex]; - if (!tablesStream.TryReadColumn24(tableSource, tableSourceRid, column, out uint startRid)) - return RidList.Empty; - bool hasNext = tablesStream.TryReadColumn24(tableSource, tableSourceRid + 1, column, out uint nextListRid); - uint lastRid = tableDest.Rows + 1; - if (startRid == 0 || startRid >= lastRid) - return RidList.Empty; - uint endRid = !hasNext || (nextListRid == 0 && tableSourceRid + 1 == tableSource.Rows && tableDest.Rows == 0xFFFF) ? lastRid : nextListRid; - if (endRid < startRid) - endRid = startRid; - if (endRid > lastRid) - endRid = lastRid; - return RidList.Create(startRid, endRid - startRid); - } - - /// - protected override uint BinarySearch(MDTable tableSource, int keyColIndex, uint key) { - var keyColumn = tableSource.TableInfo.Columns[keyColIndex]; - uint ridLo = 1, ridHi = tableSource.Rows; - while (ridLo <= ridHi) { - uint rid = (ridLo + ridHi) / 2; - if (!tablesStream.TryReadColumn24(tableSource, rid, keyColumn, out uint key2)) - break; // Never happens since rid is valid - if (key == key2) - return rid; - if (key2 > key) - ridHi = rid - 1; - else - ridLo = rid + 1; - } - - return 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/CustomDotNetStream.cs b/Plugins/dnlib/DotNet/MD/CustomDotNetStream.cs deleted file mode 100644 index d7a9142..0000000 --- a/Plugins/dnlib/DotNet/MD/CustomDotNetStream.cs +++ /dev/null @@ -1,25 +0,0 @@ -// 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/Plugins/dnlib/DotNet/MD/DotNetStream.cs b/Plugins/dnlib/DotNet/MD/DotNetStream.cs deleted file mode 100644 index b6e6f3c..0000000 --- a/Plugins/dnlib/DotNet/MD/DotNetStream.cs +++ /dev/null @@ -1,154 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// .NET metadata stream - /// - [DebuggerDisplay("{dataReader.Length} {streamHeader.Name}")] - public abstract class DotNetStream : IFileSection, IDisposable { - /// - /// Reader that can access the whole stream. - /// - /// NOTE: Always copy this field to a local variable before using it since it must be thread safe. - /// - protected DataReader dataReader; - - /// - /// null if it wasn't present in the file - /// - StreamHeader streamHeader; - - DataReaderFactory mdReaderFactory; - uint metadataBaseOffset; - - /// - public FileOffset StartOffset => (FileOffset)dataReader.StartOffset; - - /// - public FileOffset EndOffset => (FileOffset)dataReader.EndOffset; - - /// - /// Gets the length of this stream in the metadata - /// - public uint StreamLength => dataReader.Length; - - /// - /// Gets the stream header - /// - public StreamHeader StreamHeader => streamHeader; - - /// - /// Gets the name of the stream - /// - public string Name => streamHeader is null ? string.Empty : streamHeader.Name; - - /// - /// Gets a data reader that can read the full stream - /// - /// - public DataReader CreateReader() => dataReader; - - /// - /// Default constructor - /// - protected DotNetStream() { - streamHeader = null; - dataReader = default; - } - - /// - /// Constructor - /// - /// Data reader factory - /// Offset of metadata - /// The stream header - protected DotNetStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) { - this.mdReaderFactory = mdReaderFactory; - mdReaderFactory.DataReaderInvalidated += DataReaderFactory_DataReaderInvalidated; - this.mdReaderFactory = mdReaderFactory; - this.metadataBaseOffset = metadataBaseOffset; - this.streamHeader = streamHeader; - RecreateReader(mdReaderFactory, metadataBaseOffset, streamHeader, notifyThisClass: false); - } - - 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 is null || streamHeader is null) - dataReader = default; - else - dataReader = mdReaderFactory.CreateReader(metadataBaseOffset + streamHeader.Offset, streamHeader.StreamSize); - if (notifyThisClass) - OnReaderRecreated(); - } - - /// - /// Called after gets recreated - /// - protected virtual void OnReaderRecreated() { } - - /// - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose method - /// - /// true if called by - protected virtual void Dispose(bool disposing) { - if (disposing) { - var mdReaderFactory = this.mdReaderFactory; - if (mdReaderFactory is not null) - mdReaderFactory.DataReaderInvalidated -= DataReaderFactory_DataReaderInvalidated; - streamHeader = null; - this.mdReaderFactory = null; - } - } - - /// - /// Checks whether an index is valid - /// - /// The index - /// true if the index is valid - 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) => offset == 0 || offset < dataReader.Length; - - /// - /// Check whether an offset is within the stream - /// - /// Stream offset - /// Size of data - /// true if the offset is valid - public bool IsValidOffset(uint offset, int size) { - if (size == 0) - return IsValidOffset(offset); - return size > 0 && (ulong)offset + (uint)size <= dataReader.Length; - } - } - - /// - /// Base class of #US, #Strings, #Blob, and #GUID classes - /// - public abstract class HeapStream : DotNetStream { - /// - protected HeapStream() { - } - - /// - protected HeapStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/DotNetTableSizes.cs b/Plugins/dnlib/DotNet/MD/DotNetTableSizes.cs deleted file mode 100644 index 26ea002..0000000 --- a/Plugins/dnlib/DotNet/MD/DotNetTableSizes.cs +++ /dev/null @@ -1,408 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet.MD { - /// - /// Initializes .NET table row sizes - /// - public sealed class DotNetTableSizes { - bool bigStrings; - bool bigGuid; - bool bigBlob; - bool forceAllBig; - TableInfo[] tableInfos; - - internal static bool IsSystemTable(Table table) => 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 - /// Count of rows in each table (debug tables) - 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; - foreach (var colInfo in tableInfo.Columns) { - colInfo.Offset = colOffset; - var colSize = GetSize(colInfo.ColumnSize, rowCounts); - colInfo.Size = colSize; - colOffset += colSize; - } - tableInfo.RowSize = colOffset; - } - } - - 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 forceAllBig || count > 0xFFFF ? 4 : 2; - } - else if (ColumnSize.TypeDefOrRef <= columnSize && columnSize <= ColumnSize.HasCustomDebugInformation) { - 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; - var tableRows = index >= rowCounts.Count ? 0 : rowCounts[index]; - if (tableRows > maxRows) - maxRows = tableRows; - } - // Can't overflow since maxRows <= 0x00FFFFFF and info.Bits < 8 - uint finalRows = maxRows << info.Bits; - return forceAllBig || finalRows > 0xFFFF ? 4 : 2; - } - else { - switch (columnSize) { - case ColumnSize.Byte: return 1; - case ColumnSize.Int16: return 2; - case ColumnSize.UInt16: return 2; - case ColumnSize.Int32: return 4; - case ColumnSize.UInt32: return 4; - 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}"); - } - - /// - /// Creates the table infos - /// - /// Major table version - /// Minor table version - /// All table infos (not completely initialized) - public TableInfo[] CreateTables(byte majorVersion, byte minorVersion) => - CreateTables(majorVersion, minorVersion, out int maxPresentTables); - - internal const int normalMaxTables = (int)Table.CustomDebugInformation + 1; - - /// - /// Creates the table infos - /// - /// Major table version - /// Minor table version - /// 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) { - maxPresentTables = (majorVersion == 1 && minorVersion == 0) ? (int)Table.NestedClass + 1 : normalMaxTables; - - var tableInfos = new TableInfo[normalMaxTables]; - - tableInfos[(int)Table.Module] = new TableInfo(Table.Module, "Module", new ColumnInfo[] { - new ColumnInfo(0, "Generation", ColumnSize.UInt16), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Mvid", ColumnSize.GUID), - new ColumnInfo(3, "EncId", ColumnSize.GUID), - new ColumnInfo(4, "EncBaseId", ColumnSize.GUID), - }); - tableInfos[(int)Table.TypeRef] = new TableInfo(Table.TypeRef, "TypeRef", new ColumnInfo[] { - new ColumnInfo(0, "ResolutionScope", ColumnSize.ResolutionScope), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Namespace", ColumnSize.Strings), - }); - tableInfos[(int)Table.TypeDef] = new TableInfo(Table.TypeDef, "TypeDef", new ColumnInfo[] { - new ColumnInfo(0, "Flags", ColumnSize.UInt32), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Namespace", ColumnSize.Strings), - new ColumnInfo(3, "Extends", ColumnSize.TypeDefOrRef), - new ColumnInfo(4, "FieldList", ColumnSize.Field), - new ColumnInfo(5, "MethodList", ColumnSize.Method), - }); - tableInfos[(int)Table.FieldPtr] = new TableInfo(Table.FieldPtr, "FieldPtr", new ColumnInfo[] { - new ColumnInfo(0, "Field", ColumnSize.Field), - }); - tableInfos[(int)Table.Field] = new TableInfo(Table.Field, "Field", new ColumnInfo[] { - new ColumnInfo(0, "Flags", ColumnSize.UInt16), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Signature", ColumnSize.Blob), - }); - tableInfos[(int)Table.MethodPtr] = new TableInfo(Table.MethodPtr, "MethodPtr", new ColumnInfo[] { - new ColumnInfo(0, "Method", ColumnSize.Method), - }); - tableInfos[(int)Table.Method] = new TableInfo(Table.Method, "Method", new ColumnInfo[] { - new ColumnInfo(0, "RVA", ColumnSize.UInt32), - new ColumnInfo(1, "ImplFlags", ColumnSize.UInt16), - new ColumnInfo(2, "Flags", ColumnSize.UInt16), - new ColumnInfo(3, "Name", ColumnSize.Strings), - new ColumnInfo(4, "Signature", ColumnSize.Blob), - new ColumnInfo(5, "ParamList", ColumnSize.Param), - }); - tableInfos[(int)Table.ParamPtr] = new TableInfo(Table.ParamPtr, "ParamPtr", new ColumnInfo[] { - new ColumnInfo(0, "Param", ColumnSize.Param), - }); - tableInfos[(int)Table.Param] = new TableInfo(Table.Param, "Param", new ColumnInfo[] { - new ColumnInfo(0, "Flags", ColumnSize.UInt16), - new ColumnInfo(1, "Sequence", ColumnSize.UInt16), - new ColumnInfo(2, "Name", ColumnSize.Strings), - }); - tableInfos[(int)Table.InterfaceImpl] = new TableInfo(Table.InterfaceImpl, "InterfaceImpl", new ColumnInfo[] { - new ColumnInfo(0, "Class", ColumnSize.TypeDef), - new ColumnInfo(1, "Interface", ColumnSize.TypeDefOrRef), - }); - tableInfos[(int)Table.MemberRef] = new TableInfo(Table.MemberRef, "MemberRef", new ColumnInfo[] { - new ColumnInfo(0, "Class", ColumnSize.MemberRefParent), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Signature", ColumnSize.Blob), - }); - tableInfos[(int)Table.Constant] = new TableInfo(Table.Constant, "Constant", new ColumnInfo[] { - new ColumnInfo(0, "Type", ColumnSize.Byte), - new ColumnInfo(1, "Padding", ColumnSize.Byte), - new ColumnInfo(2, "Parent", ColumnSize.HasConstant), - new ColumnInfo(3, "Value", ColumnSize.Blob), - }); - tableInfos[(int)Table.CustomAttribute] = new TableInfo(Table.CustomAttribute, "CustomAttribute", new ColumnInfo[] { - new ColumnInfo(0, "Parent", ColumnSize.HasCustomAttribute), - new ColumnInfo(1, "Type", ColumnSize.CustomAttributeType), - new ColumnInfo(2, "Value", ColumnSize.Blob), - }); - tableInfos[(int)Table.FieldMarshal] = new TableInfo(Table.FieldMarshal, "FieldMarshal", new ColumnInfo[] { - new ColumnInfo(0, "Parent", ColumnSize.HasFieldMarshal), - new ColumnInfo(1, "NativeType", ColumnSize.Blob), - }); - tableInfos[(int)Table.DeclSecurity] = new TableInfo(Table.DeclSecurity, "DeclSecurity", new ColumnInfo[] { - new ColumnInfo(0, "Action", ColumnSize.Int16), - new ColumnInfo(1, "Parent", ColumnSize.HasDeclSecurity), - new ColumnInfo(2, "PermissionSet", ColumnSize.Blob), - }); - tableInfos[(int)Table.ClassLayout] = new TableInfo(Table.ClassLayout, "ClassLayout", new ColumnInfo[] { - new ColumnInfo(0, "PackingSize", ColumnSize.UInt16), - new ColumnInfo(1, "ClassSize", ColumnSize.UInt32), - new ColumnInfo(2, "Parent", ColumnSize.TypeDef), - }); - tableInfos[(int)Table.FieldLayout] = new TableInfo(Table.FieldLayout, "FieldLayout", new ColumnInfo[] { - new ColumnInfo(0, "OffSet", ColumnSize.UInt32), - new ColumnInfo(1, "Field", ColumnSize.Field), - }); - tableInfos[(int)Table.StandAloneSig] = new TableInfo(Table.StandAloneSig, "StandAloneSig", new ColumnInfo[] { - new ColumnInfo(0, "Signature", ColumnSize.Blob), - }); - tableInfos[(int)Table.EventMap] = new TableInfo(Table.EventMap, "EventMap", new ColumnInfo[] { - new ColumnInfo(0, "Parent", ColumnSize.TypeDef), - new ColumnInfo(1, "EventList", ColumnSize.Event), - }); - tableInfos[(int)Table.EventPtr] = new TableInfo(Table.EventPtr, "EventPtr", new ColumnInfo[] { - new ColumnInfo(0, "Event", ColumnSize.Event), - }); - tableInfos[(int)Table.Event] = new TableInfo(Table.Event, "Event", new ColumnInfo[] { - new ColumnInfo(0, "EventFlags", ColumnSize.UInt16), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "EventType", ColumnSize.TypeDefOrRef), - }); - tableInfos[(int)Table.PropertyMap] = new TableInfo(Table.PropertyMap, "PropertyMap", new ColumnInfo[] { - new ColumnInfo(0, "Parent", ColumnSize.TypeDef), - new ColumnInfo(1, "PropertyList", ColumnSize.Property), - }); - tableInfos[(int)Table.PropertyPtr] = new TableInfo(Table.PropertyPtr, "PropertyPtr", new ColumnInfo[] { - new ColumnInfo(0, "Property", ColumnSize.Property), - }); - tableInfos[(int)Table.Property] = new TableInfo(Table.Property, "Property", new ColumnInfo[] { - new ColumnInfo(0, "PropFlags", ColumnSize.UInt16), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "Type", ColumnSize.Blob), - }); - tableInfos[(int)Table.MethodSemantics] = new TableInfo(Table.MethodSemantics, "MethodSemantics", new ColumnInfo[] { - new ColumnInfo(0, "Semantic", ColumnSize.UInt16), - new ColumnInfo(1, "Method", ColumnSize.Method), - new ColumnInfo(2, "Association", ColumnSize.HasSemantic), - }); - tableInfos[(int)Table.MethodImpl] = new TableInfo(Table.MethodImpl, "MethodImpl", new ColumnInfo[] { - new ColumnInfo(0, "Class", ColumnSize.TypeDef), - new ColumnInfo(1, "MethodBody", ColumnSize.MethodDefOrRef), - new ColumnInfo(2, "MethodDeclaration", ColumnSize.MethodDefOrRef), - }); - tableInfos[(int)Table.ModuleRef] = new TableInfo(Table.ModuleRef, "ModuleRef", new ColumnInfo[] { - new ColumnInfo(0, "Name", ColumnSize.Strings), - }); - tableInfos[(int)Table.TypeSpec] = new TableInfo(Table.TypeSpec, "TypeSpec", new ColumnInfo[] { - new ColumnInfo(0, "Signature", ColumnSize.Blob), - }); - tableInfos[(int)Table.ImplMap] = new TableInfo(Table.ImplMap, "ImplMap", new ColumnInfo[] { - new ColumnInfo(0, "MappingFlags", ColumnSize.UInt16), - new ColumnInfo(1, "MemberForwarded", ColumnSize.MemberForwarded), - new ColumnInfo(2, "ImportName", ColumnSize.Strings), - new ColumnInfo(3, "ImportScope", ColumnSize.ModuleRef), - }); - tableInfos[(int)Table.FieldRVA] = new TableInfo(Table.FieldRVA, "FieldRVA", new ColumnInfo[] { - new ColumnInfo(0, "RVA", ColumnSize.UInt32), - new ColumnInfo(1, "Field", ColumnSize.Field), - }); - tableInfos[(int)Table.ENCLog] = new TableInfo(Table.ENCLog, "ENCLog", new ColumnInfo[] { - new ColumnInfo(0, "Token", ColumnSize.UInt32), - new ColumnInfo(1, "FuncCode", ColumnSize.UInt32), - }); - tableInfos[(int)Table.ENCMap] = new TableInfo(Table.ENCMap, "ENCMap", new ColumnInfo[] { - new ColumnInfo(0, "Token", ColumnSize.UInt32), - }); - tableInfos[(int)Table.Assembly] = new TableInfo(Table.Assembly, "Assembly", new ColumnInfo[] { - new ColumnInfo(0, "HashAlgId", ColumnSize.UInt32), - new ColumnInfo(1, "MajorVersion", ColumnSize.UInt16), - new ColumnInfo(2, "MinorVersion", ColumnSize.UInt16), - new ColumnInfo(3, "BuildNumber", ColumnSize.UInt16), - new ColumnInfo(4, "RevisionNumber", ColumnSize.UInt16), - new ColumnInfo(5, "Flags", ColumnSize.UInt32), - new ColumnInfo(6, "PublicKey", ColumnSize.Blob), - new ColumnInfo(7, "Name", ColumnSize.Strings), - new ColumnInfo(8, "Locale", ColumnSize.Strings), - }); - tableInfos[(int)Table.AssemblyProcessor] = new TableInfo(Table.AssemblyProcessor, "AssemblyProcessor", new ColumnInfo[] { - new ColumnInfo(0, "Processor", ColumnSize.UInt32), - }); - tableInfos[(int)Table.AssemblyOS] = new TableInfo(Table.AssemblyOS, "AssemblyOS", new ColumnInfo[] { - new ColumnInfo(0, "OSPlatformId", ColumnSize.UInt32), - new ColumnInfo(1, "OSMajorVersion", ColumnSize.UInt32), - new ColumnInfo(2, "OSMinorVersion", ColumnSize.UInt32), - }); - tableInfos[(int)Table.AssemblyRef] = new TableInfo(Table.AssemblyRef, "AssemblyRef", new ColumnInfo[] { - new ColumnInfo(0, "MajorVersion", ColumnSize.UInt16), - new ColumnInfo(1, "MinorVersion", ColumnSize.UInt16), - new ColumnInfo(2, "BuildNumber", ColumnSize.UInt16), - new ColumnInfo(3, "RevisionNumber", ColumnSize.UInt16), - new ColumnInfo(4, "Flags", ColumnSize.UInt32), - new ColumnInfo(5, "PublicKeyOrToken", ColumnSize.Blob), - new ColumnInfo(6, "Name", ColumnSize.Strings), - new ColumnInfo(7, "Locale", ColumnSize.Strings), - new ColumnInfo(8, "HashValue", ColumnSize.Blob), - }); - tableInfos[(int)Table.AssemblyRefProcessor] = new TableInfo(Table.AssemblyRefProcessor, "AssemblyRefProcessor", new ColumnInfo[] { - new ColumnInfo(0, "Processor", ColumnSize.UInt32), - new ColumnInfo(1, "AssemblyRef", ColumnSize.AssemblyRef), - }); - tableInfos[(int)Table.AssemblyRefOS] = new TableInfo(Table.AssemblyRefOS, "AssemblyRefOS", new ColumnInfo[] { - new ColumnInfo(0, "OSPlatformId", ColumnSize.UInt32), - new ColumnInfo(1, "OSMajorVersion", ColumnSize.UInt32), - new ColumnInfo(2, "OSMinorVersion", ColumnSize.UInt32), - new ColumnInfo(3, "AssemblyRef", ColumnSize.AssemblyRef), - }); - tableInfos[(int)Table.File] = new TableInfo(Table.File, "File", new ColumnInfo[] { - new ColumnInfo(0, "Flags", ColumnSize.UInt32), - new ColumnInfo(1, "Name", ColumnSize.Strings), - new ColumnInfo(2, "HashValue", ColumnSize.Blob), - }); - tableInfos[(int)Table.ExportedType] = new TableInfo(Table.ExportedType, "ExportedType", new ColumnInfo[] { - new ColumnInfo(0, "Flags", ColumnSize.UInt32), - new ColumnInfo(1, "TypeDefId", ColumnSize.UInt32), - new ColumnInfo(2, "TypeName", ColumnSize.Strings), - new ColumnInfo(3, "TypeNamespace", ColumnSize.Strings), - new ColumnInfo(4, "Implementation", ColumnSize.Implementation), - }); - tableInfos[(int)Table.ManifestResource] = new TableInfo(Table.ManifestResource, "ManifestResource", new ColumnInfo[] { - new ColumnInfo(0, "Offset", ColumnSize.UInt32), - new ColumnInfo(1, "Flags", ColumnSize.UInt32), - new ColumnInfo(2, "Name", ColumnSize.Strings), - new ColumnInfo(3, "Implementation", ColumnSize.Implementation), - }); - tableInfos[(int)Table.NestedClass] = new TableInfo(Table.NestedClass, "NestedClass", new ColumnInfo[] { - new ColumnInfo(0, "NestedClass", ColumnSize.TypeDef), - new ColumnInfo(1, "EnclosingClass", ColumnSize.TypeDef), - }); - if (majorVersion == 1 && minorVersion == 1) { - tableInfos[(int)Table.GenericParam] = new TableInfo(Table.GenericParam, "GenericParam", new ColumnInfo[] { - new ColumnInfo(0, "Number", ColumnSize.UInt16), - new ColumnInfo(1, "Flags", ColumnSize.UInt16), - new ColumnInfo(2, "Owner", ColumnSize.TypeOrMethodDef), - new ColumnInfo(3, "Name", ColumnSize.Strings), - new ColumnInfo(4, "Kind", ColumnSize.TypeDefOrRef), - }); - } - else { - tableInfos[(int)Table.GenericParam] = new TableInfo(Table.GenericParam, "GenericParam", new ColumnInfo[] { - new ColumnInfo(0, "Number", ColumnSize.UInt16), - new ColumnInfo(1, "Flags", ColumnSize.UInt16), - new ColumnInfo(2, "Owner", ColumnSize.TypeOrMethodDef), - new ColumnInfo(3, "Name", ColumnSize.Strings), - }); - } - tableInfos[(int)Table.MethodSpec] = new TableInfo(Table.MethodSpec, "MethodSpec", new ColumnInfo[] { - new ColumnInfo(0, "Method", ColumnSize.MethodDefOrRef), - new ColumnInfo(1, "Instantiation", ColumnSize.Blob), - }); - tableInfos[(int)Table.GenericParamConstraint] = new TableInfo(Table.GenericParamConstraint, "GenericParamConstraint", new ColumnInfo[] { - 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/Plugins/dnlib/DotNet/MD/ENCMetadata.cs b/Plugins/dnlib/DotNet/MD/ENCMetadata.cs deleted file mode 100644 index 5e8645f..0000000 --- a/Plugins/dnlib/DotNet/MD/ENCMetadata.cs +++ /dev/null @@ -1,518 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.IO; -using dnlib.PE; -using dnlib.Threading; - -namespace dnlib.DotNet.MD { - /// - /// Used when a #- stream is present in the metadata - /// - sealed class ENCMetadata : MetadataBase { - static readonly UTF8String DeletedName = "_Deleted"; - bool hasMethodPtr, hasFieldPtr, hasParamPtr, hasEventPtr, hasPropertyPtr; - bool hasDeletedFields; - bool hasDeletedNonFields; - readonly CLRRuntimeReaderKind runtime; - readonly Dictionary sortedTables = new Dictionary(); -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public override bool IsCompressed => false; - - /// - public ENCMetadata(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader, CLRRuntimeReaderKind runtime) - : base(peImage, cor20Header, mdHeader) { - this.runtime = runtime; - } - - /// - 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; - bool forceAllBig = false; - try { - 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 "#~": - 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); - newAllStreams.Add(pdbStream); - continue; - } - break; - - case "#JTD": - forceAllBig = true; - 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; - - case "#JTD": - forceAllBig = true; - continue; - } - dns = new CustomDotNetStream(mdReaderFactory, metadataBaseOffset, sh); - allStreams.Add(dns); - dns = null; - } - } - } - finally { - dns?.Dispose(); - } - - if (tablesStream is null) - throw new BadImageFormatException("Missing MD stream"); - - if (pdbStream is not null) - tablesStream.Initialize(pdbStream.TypeSystemTableRows, forceAllBig); - else - tablesStream.Initialize(null, forceAllBig); - - // The pointer tables are used iff row count != 0 - hasFieldPtr = !tablesStream.FieldPtrTable.IsEmpty; - hasMethodPtr = !tablesStream.MethodPtrTable.IsEmpty; - hasParamPtr = !tablesStream.ParamPtrTable.IsEmpty; - hasEventPtr = !tablesStream.EventPtrTable.IsEmpty; - hasPropertyPtr = !tablesStream.PropertyPtrTable.IsEmpty; - - 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 (!hasDeletedNonFields) - return base.GetTypeDefRidList(); - uint rows = tablesStream.TypeDefTable.Rows; - var list = new List((int)rows); - for (uint rid = 1; rid <= rows; rid++) { - if (!tablesStream.TryReadTypeDefRow(rid, out var row)) - continue; // Should never happen since rid is valid - - // RTSpecialName is ignored by the CLR. It's only the name that indicates - // whether it's been deleted. - // 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); - } - return RidList.Create(list); - } - - /// - public override RidList GetExportedTypeRidList() { - if (!hasDeletedNonFields) - return base.GetExportedTypeRidList(); - uint rows = tablesStream.ExportedTypeTable.Rows; - var list = new List((int)rows); - for (uint rid = 1; rid <= rows; rid++) { - if (!tablesStream.TryReadExportedTypeRow(rid, out var row)) - continue; // Should never happen since rid is valid - - // RTSpecialName is ignored by the CLR. It's only the name that indicates - // whether it's been deleted. - if (stringsStream.ReadNoNull(row.TypeName).StartsWith(DeletedName)) - continue; // ignore this deleted row - list.Add(rid); - } - return RidList.Create(list); - } - - /// - /// Converts a logical Field rid to a physical Field rid - /// - /// A valid rid - /// Converted rid or any invalid rid value if is invalid - uint ToFieldRid(uint listRid) { - if (!hasFieldPtr) - return listRid; - return tablesStream.TryReadColumn24(tablesStream.FieldPtrTable, listRid, 0, out uint listValue) ? listValue : 0; - } - - /// - /// Converts a logical Method rid to a physical Method rid - /// - /// A valid rid - /// Converted rid or any invalid rid value if is invalid - uint ToMethodRid(uint listRid) { - if (!hasMethodPtr) - return listRid; - return tablesStream.TryReadColumn24(tablesStream.MethodPtrTable, listRid, 0, out uint listValue) ? listValue : 0; - } - - /// - /// Converts a logical Param rid to a physical Param rid - /// - /// A valid rid - /// Converted rid or any invalid rid value if is invalid - uint ToParamRid(uint listRid) { - if (!hasParamPtr) - return listRid; - return tablesStream.TryReadColumn24(tablesStream.ParamPtrTable, listRid, 0, out uint listValue) ? listValue : 0; - } - - /// - /// Converts a logical Event rid to a physical Event rid - /// - /// A valid rid - /// Converted rid or any invalid rid value if is invalid - uint ToEventRid(uint listRid) { - if (!hasEventPtr) - return listRid; - return tablesStream.TryReadColumn24(tablesStream.EventPtrTable, listRid, 0, out uint listValue) ? listValue : 0; - } - - /// - /// Converts a logical Property rid to a physical Property rid - /// - /// A valid rid - /// Converted rid or any invalid rid value if is invalid - uint ToPropertyRid(uint listRid) { - if (!hasPropertyPtr) - return listRid; - return tablesStream.TryReadColumn24(tablesStream.PropertyPtrTable, listRid, 0, out uint listValue) ? listValue : 0; - } - - /// - public override RidList GetFieldRidList(uint typeDefRid) { - var list = GetRidList(tablesStream.TypeDefTable, typeDefRid, 4, tablesStream.FieldTable); - if (list.Count == 0 || (!hasFieldPtr && !hasDeletedFields)) - return list; - - var destTable = tablesStream.FieldTable; - var newList = new List(list.Count); - for (int i = 0; i < list.Count; i++) { - var rid = ToFieldRid(list[i]); - if (destTable.IsInvalidRID(rid)) - continue; - 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 (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 - newList.Add(rid); - } - return RidList.Create(newList); - } - - /// - public override RidList GetMethodRidList(uint typeDefRid) { - var list = GetRidList(tablesStream.TypeDefTable, typeDefRid, 5, tablesStream.MethodTable); - if (list.Count == 0 || (!hasMethodPtr && !hasDeletedNonFields)) - return list; - - var destTable = tablesStream.MethodTable; - var newList = new List(list.Count); - for (int i = 0; i < list.Count; i++) { - var rid = ToMethodRid(list[i]); - if (destTable.IsInvalidRID(rid)) - continue; - 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 - if ((row.Flags & (uint)MethodAttributes.RTSpecialName) != 0) { - if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) - continue; // ignore this deleted row - } - } - // It's a valid non-deleted rid so add it - newList.Add(rid); - } - return RidList.Create(newList); - } - - /// - public override RidList GetParamRidList(uint methodRid) { - var list = GetRidList(tablesStream.MethodTable, methodRid, 5, tablesStream.ParamTable); - if (list.Count == 0 || !hasParamPtr) - return list; - - var destTable = tablesStream.ParamTable; - var newList = new List(list.Count); - for (int i = 0; i < list.Count; i++) { - var rid = ToParamRid(list[i]); - if (destTable.IsInvalidRID(rid)) - continue; - newList.Add(rid); - } - return RidList.Create(newList); - } - - /// - public override RidList GetEventRidList(uint eventMapRid) { - var list = GetRidList(tablesStream.EventMapTable, eventMapRid, 1, tablesStream.EventTable); - if (list.Count == 0 || (!hasEventPtr && !hasDeletedNonFields)) - return list; - - var destTable = tablesStream.EventTable; - var newList = new List(list.Count); - for (int i = 0; i < list.Count; i++) { - var rid = ToEventRid(list[i]); - if (destTable.IsInvalidRID(rid)) - continue; - 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 - if ((row.EventFlags & (uint)EventAttributes.RTSpecialName) != 0) { - if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) - continue; // ignore this deleted row - } - } - // It's a valid non-deleted rid so add it - newList.Add(rid); - } - return RidList.Create(newList); - } - - /// - public override RidList GetPropertyRidList(uint propertyMapRid) { - var list = GetRidList(tablesStream.PropertyMapTable, propertyMapRid, 1, tablesStream.PropertyTable); - if (list.Count == 0 || (!hasPropertyPtr && !hasDeletedNonFields)) - return list; - - var destTable = tablesStream.PropertyTable; - var newList = new List(list.Count); - for (int i = 0; i < list.Count; i++) { - var rid = ToPropertyRid(list[i]); - if (destTable.IsInvalidRID(rid)) - continue; - 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 - if ((row.PropFlags & (uint)PropertyAttributes.RTSpecialName) != 0) { - if (stringsStream.ReadNoNull(row.Name).StartsWith(DeletedName)) - continue; // ignore this deleted row - } - } - // It's a valid non-deleted rid so add it - newList.Add(rid); - } - 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) - /// - /// Source table, eg. TypeDef - /// Row ID in - /// Column index in , eg. 4 for TypeDef.FieldList - /// Destination table, eg. Field - /// A new instance - RidList GetRidList(MDTable tableSource, uint tableSourceRid, int colIndex, MDTable tableDest) { - var column = tableSource.TableInfo.Columns[colIndex]; - if (!tablesStream.TryReadColumn24(tableSource, tableSourceRid, column, out uint startRid)) - return RidList.Empty; - bool hasNext = tablesStream.TryReadColumn24(tableSource, tableSourceRid + 1, column, out uint nextListRid); - uint lastRid = tableDest.Rows + 1; - if (startRid == 0 || startRid >= lastRid) - return RidList.Empty; - uint endRid = hasNext && nextListRid != 0 ? nextListRid : lastRid; - if (endRid < startRid) - endRid = startRid; - if (endRid > lastRid) - endRid = lastRid; - return RidList.Create(startRid, endRid - startRid); - } - - /// - protected override uint BinarySearch(MDTable tableSource, int keyColIndex, uint key) { - var keyColumn = tableSource.TableInfo.Columns[keyColIndex]; - uint ridLo = 1, ridHi = tableSource.Rows; - while (ridLo <= ridHi) { - uint rid = (ridLo + ridHi) / 2; - if (!tablesStream.TryReadColumn24(tableSource, rid, keyColumn, out uint key2)) - break; // Never happens since rid is valid - if (key == key2) - return rid; - if (key2 > key) - ridHi = rid - 1; - else - ridLo = rid + 1; - } - - if (tableSource.Table == Table.GenericParam && !tablesStream.IsSorted(tableSource)) - return LinearSearch(tableSource, keyColIndex, key); - - return 0; - } - - uint LinearSearch(MDTable tableSource, int keyColIndex, uint key) { - if (tableSource is null) - return 0; - var keyColumn = tableSource.TableInfo.Columns[keyColIndex]; - for (uint rid = 1; rid <= tableSource.Rows; rid++) { - if (!tablesStream.TryReadColumn24(tableSource, rid, keyColumn, out uint key2)) - break; // Never happens since rid is valid - if (key == key2) - return rid; - } - return 0; - } - - /// - protected override RidList FindAllRowsUnsorted(MDTable tableSource, int keyColIndex, uint key) { - if (tablesStream.IsSorted(tableSource)) - return FindAllRows(tableSource, keyColIndex, key); - SortedTable sortedTable; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (!sortedTables.TryGetValue(tableSource.Table, out sortedTable)) - sortedTables[tableSource.Table] = sortedTable = new SortedTable(tableSource, keyColIndex); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - return sortedTable.FindAllRows(key); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/GuidStream.cs b/Plugins/dnlib/DotNet/MD/GuidStream.cs deleted file mode 100644 index 0127a46..0000000 --- a/Plugins/dnlib/DotNet/MD/GuidStream.cs +++ /dev/null @@ -1,36 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Represents the #GUID stream - /// - public sealed class GuidStream : HeapStream { - /// - public GuidStream() { - } - - /// - public GuidStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - } - - /// - public override bool IsValidIndex(uint index) => index == 0 || (index <= 0x10000000 && IsValidOffset((index - 1) * 16, 16)); - - /// - /// Read a - /// - /// Index into this stream - /// A or null if is 0 or invalid - public Guid? Read(uint index) { - if (index == 0 || !IsValidIndex(index)) - return null; - var reader = dataReader; - reader.Position = (index - 1) * 16; - return reader.ReadGuid(); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/HeapType.cs b/Plugins/dnlib/DotNet/MD/HeapType.cs deleted file mode 100644 index cf3f3ed..0000000 --- a/Plugins/dnlib/DotNet/MD/HeapType.cs +++ /dev/null @@ -1,17 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.MD { - /// - /// Heap type. The values are set in stone by MS. Don't change. - /// - public enum HeapType : uint { - /// #Strings heap - Strings = 0, - /// #GUID heap - Guid = 1, - /// #Blob heap - Blob = 2, - /// #US heap - US = 3, - } -} diff --git a/Plugins/dnlib/DotNet/MD/IRowReaders.cs b/Plugins/dnlib/DotNet/MD/IRowReaders.cs deleted file mode 100644 index acb89bc..0000000 --- a/Plugins/dnlib/DotNet/MD/IRowReaders.cs +++ /dev/null @@ -1,33 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.MD { - /// - /// Reads metadata table columns - /// - public interface IColumnReader { - /// - /// Reads a column - /// - /// The table to read from - /// Table row id - /// The column to read - /// Result - /// true if was updated, false if - /// the column should be read from the original table. - bool ReadColumn(MDTable table, uint rid, ColumnInfo column, out uint value); - } - - /// - /// Reads table rows - /// - /// Raw row - public interface IRowReader where TRow : struct { - /// - /// Reads a table row or returns false if the row should be read from the original table - /// - /// Row id - /// The row - /// - bool TryReadRow(uint rid, out TRow row); - } -} diff --git a/Plugins/dnlib/DotNet/MD/ImageCor20Header.cs b/Plugins/dnlib/DotNet/MD/ImageCor20Header.cs deleted file mode 100644 index 6177466..0000000 --- a/Plugins/dnlib/DotNet/MD/ImageCor20Header.cs +++ /dev/null @@ -1,115 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.MD { - /// - /// Represents the IMAGE_COR20_HEADER structure - /// - public sealed class ImageCor20Header : FileSection { - readonly uint cb; - readonly ushort majorRuntimeVersion; - readonly ushort minorRuntimeVersion; - readonly ImageDataDirectory metadata; - readonly ComImageFlags flags; - readonly uint entryPointToken_or_RVA; - readonly ImageDataDirectory resources; - readonly ImageDataDirectory strongNameSignature; - readonly ImageDataDirectory codeManagerTable; - readonly ImageDataDirectory vtableFixups; - readonly ImageDataDirectory exportAddressTableJumps; - readonly ImageDataDirectory managedNativeHeader; - - /// - /// Returns true if it has a native header - /// - public bool HasNativeHeader => (flags & ComImageFlags.ILLibrary) != 0; - - /// - /// Returns the IMAGE_COR20_HEADER.cb field - /// - public uint CB => cb; - - /// - /// Returns the IMAGE_COR20_HEADER.MajorRuntimeVersion field - /// - public ushort MajorRuntimeVersion => majorRuntimeVersion; - - /// - /// Returns the IMAGE_COR20_HEADER.MinorRuntimeVersion field - /// - public ushort MinorRuntimeVersion => minorRuntimeVersion; - - /// - /// Returns the IMAGE_COR20_HEADER.Metadata field - /// - public ImageDataDirectory Metadata => metadata; - - /// - /// Returns the IMAGE_COR20_HEADER.Flags field - /// - public ComImageFlags Flags => flags; - - /// - /// Returns the IMAGE_COR20_HEADER.EntryPointToken/EntryPointTokenRVA field - /// - public uint EntryPointToken_or_RVA => entryPointToken_or_RVA; - - /// - /// Returns the IMAGE_COR20_HEADER.Resources field - /// - public ImageDataDirectory Resources => resources; - - /// - /// Returns the IMAGE_COR20_HEADER.StrongNameSignature field - /// - public ImageDataDirectory StrongNameSignature => strongNameSignature; - - /// - /// Returns the IMAGE_COR20_HEADER.CodeManagerTable field - /// - public ImageDataDirectory CodeManagerTable => codeManagerTable; - - /// - /// Returns the IMAGE_COR20_HEADER.VTableFixups field - /// - public ImageDataDirectory VTableFixups => vtableFixups; - - /// - /// Returns the IMAGE_COR20_HEADER.ExportAddressTableJumps field - /// - public ImageDataDirectory ExportAddressTableJumps => exportAddressTableJumps; - - /// - /// Returns the IMAGE_COR20_HEADER.ManagedNativeHeader field - /// - public ImageDataDirectory ManagedNativeHeader => managedNativeHeader; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageCor20Header(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - cb = reader.ReadUInt32(); - if (verify && cb < 0x48) - throw new BadImageFormatException("Invalid IMAGE_COR20_HEADER.cb value"); - majorRuntimeVersion = reader.ReadUInt16(); - minorRuntimeVersion = reader.ReadUInt16(); - metadata = new ImageDataDirectory(ref reader, verify); - flags = (ComImageFlags)reader.ReadUInt32(); - entryPointToken_or_RVA = reader.ReadUInt32(); - resources = new ImageDataDirectory(ref reader, verify); - strongNameSignature = new ImageDataDirectory(ref reader, verify); - codeManagerTable = new ImageDataDirectory(ref reader, verify); - vtableFixups = new ImageDataDirectory(ref reader, verify); - exportAddressTableJumps = new ImageDataDirectory(ref reader, verify); - managedNativeHeader = new ImageDataDirectory(ref reader, verify); - SetEndoffset(ref reader); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/MDHeaderRuntimeVersion.cs b/Plugins/dnlib/DotNet/MD/MDHeaderRuntimeVersion.cs deleted file mode 100644 index ab16a77..0000000 --- a/Plugins/dnlib/DotNet/MD/MDHeaderRuntimeVersion.cs +++ /dev/null @@ -1,83 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.MD { - /// - /// Version strings found in the meta data header - /// - public static class MDHeaderRuntimeVersion { - /// - /// 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 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 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 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 Framework 1.1) - /// - public const string MS_CLR_11 = "v1.1.4322"; - - /// - /// 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 Framework 4.0-4.5) - /// - public const string MS_CLR_40 = "v4.0.30319"; - - /// - /// MS CLR 1.0 any version - /// - public const string MS_CLR_10_PREFIX = "v1.0"; - - /// - /// MS CLR 1.0 any version - /// - public const string MS_CLR_10_PREFIX_X86RETAIL = "v1.x86"; - - /// - /// MS CLR 1.1 any version - /// - public const string MS_CLR_11_PREFIX = "v1.1"; - - /// - /// MS CLR 2.0 any version - /// - public const string MS_CLR_20_PREFIX = "v2.0"; - - /// - /// MS CLR 4.0 any version - /// - public const string MS_CLR_40_PREFIX = "v4.0"; - - /// - /// ECMA 2002 version string - /// - public const string ECMA_2002 = "Standard CLI 2002"; - - /// - /// 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/Plugins/dnlib/DotNet/MD/MDStreamFlags.cs b/Plugins/dnlib/DotNet/MD/MDStreamFlags.cs deleted file mode 100644 index 92c938f..0000000 --- a/Plugins/dnlib/DotNet/MD/MDStreamFlags.cs +++ /dev/null @@ -1,26 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.MD { - /// - /// MDStream flags - /// - [Flags] - public enum MDStreamFlags : byte { - /// #Strings stream is big and requires 4 byte offsets - BigStrings = 1, - /// #GUID stream is big and requires 4 byte offsets - BigGUID = 2, - /// #Blob stream is big and requires 4 byte offsets - BigBlob = 4, - /// - Padding = 8, - /// - DeltaOnly = 0x20, - /// Extra data follows the row counts - ExtraData = 0x40, - /// Set if certain tables can contain deleted rows. The name column (if present) is set to "_Deleted" - HasDelete = 0x80, - } -} diff --git a/Plugins/dnlib/DotNet/MD/MDTable.cs b/Plugins/dnlib/DotNet/MD/MDTable.cs deleted file mode 100644 index a7bcdf6..0000000 --- a/Plugins/dnlib/DotNet/MD/MDTable.cs +++ /dev/null @@ -1,122 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// A MD table (eg. Method table) - /// - [DebuggerDisplay("DL:{dataReader.Length} R:{numRows} RS:{tableInfo.RowSize} C:{Count} {tableInfo.Name}")] - public sealed class MDTable : IDisposable, IFileSection { - readonly Table table; - uint numRows; - TableInfo tableInfo; - DataReader dataReader; - - // Fix for VS2015 expression evaluator: "The debugger is unable to evaluate this expression" - int Count => tableInfo.Columns.Length; - - /// - public FileOffset StartOffset => (FileOffset)dataReader.StartOffset; - - /// - public FileOffset EndOffset => (FileOffset)dataReader.EndOffset; - - /// - /// Gets the table - /// - public Table Table => table; - - /// - /// Gets the name of this table - /// - public string Name => tableInfo.Name; - - /// - /// Returns total number of rows - /// - public uint Rows => numRows; - - /// - /// Gets the total size in bytes of one row in this table - /// - public uint RowSize => (uint)tableInfo.RowSize; - - /// - /// Returns all the columns - /// - public IList Columns => tableInfo.Columns; - - /// - /// Returns true if there are no valid rows - /// - public bool IsEmpty => numRows == 0; - - /// - /// Returns info about this table - /// - public TableInfo TableInfo => tableInfo; - - internal DataReader DataReader { - get => dataReader; - set => dataReader = value; - } - - /// - /// Constructor - /// - /// The table - /// Number of rows in this table - /// Info about this table - internal MDTable(Table table, uint numRows, TableInfo tableInfo) { - this.table = table; - this.numRows = numRows; - this.tableInfo = tableInfo; - - var columns = tableInfo.Columns; - 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 - internal readonly ColumnInfo Column0; - internal readonly ColumnInfo Column1; - internal readonly ColumnInfo Column2; - internal readonly ColumnInfo Column3; - internal readonly ColumnInfo Column4; - internal readonly ColumnInfo Column5; - internal readonly ColumnInfo Column6; - internal readonly ColumnInfo Column7; - internal readonly ColumnInfo Column8; - - /// - /// Checks whether the row exists - /// - /// Row ID - public bool IsValidRID(uint rid) => rid != 0 && rid <= numRows; - - /// - /// Checks whether the row does not exist - /// - /// Row ID - public bool IsInvalidRID(uint rid) => rid == 0 || rid > numRows; - - /// - public void Dispose() { - numRows = 0; - tableInfo = null; - dataReader = default; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/Metadata.cs b/Plugins/dnlib/DotNet/MD/Metadata.cs deleted file mode 100644 index 6d25011..0000000 --- a/Plugins/dnlib/DotNet/MD/Metadata.cs +++ /dev/null @@ -1,371 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.PE; - -namespace dnlib.DotNet.MD { - /// - /// Reads .NET metadata - /// - public abstract class Metadata : IDisposable { - /// - /// true if the compressed (normal) metadata is used, false if the non-compressed - /// (Edit N' Continue) metadata is used. This can be false even if the table stream - /// is #~ but that's very uncommon. - /// - public abstract bool IsCompressed { get; } - - /// - /// true if this is standalone Portable PDB metadata - /// - public abstract bool IsStandalonePortablePdb { get; } - - /// - /// Gets the .NET header - /// - public abstract ImageCor20Header ImageCor20Header { get; } - - /// - /// Gets the version found in the metadata header. The major version number is in the high 16 bits - /// and the lower version number is in the low 16 bits. - /// - public abstract uint Version { get; } - - /// - /// Gets the version string found in the metadata header - /// - public abstract string VersionString { get; } - - /// - /// Gets the - /// - public abstract IPEImage PEImage { get; } - - /// - /// Gets the metadata header - /// - public abstract MetadataHeader MetadataHeader { get; } - - /// - /// Returns the #Strings stream or a default empty one if it's not present - /// - public abstract StringsStream StringsStream { get; } - - /// - /// Returns the #US stream or a default empty one if it's not present - /// - public abstract USStream USStream { get; } - - /// - /// Returns the #Blob stream or a default empty one if it's not present - /// - public abstract BlobStream BlobStream { get; } - - /// - /// Returns the #GUID stream or a default empty one if it's not present - /// - public abstract GuidStream GuidStream { get; } - - /// - /// Returns the #~ or #- tables stream - /// - public abstract TablesStream TablesStream { get; } - - /// - /// Returns the #Pdb stream or null if it's not a standalone portable PDB file - /// - public abstract PdbStream PdbStream { get; } - - /// - /// Gets all streams - /// - public abstract IList AllStreams { get; } - - /// - /// Gets a list of all the valid TypeDef rids. It's usually every rid in the - /// TypeDef table, but could be less if a type has been deleted. - /// - public abstract RidList GetTypeDefRidList(); - - /// - /// Gets a list of all the valid ExportedType rids. It's usually every rid in the - /// ExportedType table, but could be less if a type has been deleted. - /// - public abstract RidList GetExportedTypeRidList(); - - /// - /// Gets the Field rid list - /// - /// TypeDef rid - /// A new instance - public abstract RidList GetFieldRidList(uint typeDefRid); - - /// - /// Gets the Method rid list - /// - /// TypeDef rid - /// A new instance - public abstract RidList GetMethodRidList(uint typeDefRid); - - /// - /// Gets the Param rid list - /// - /// Method rid - /// A new instance - public abstract RidList GetParamRidList(uint methodRid); - - /// - /// Gets the Event rid list - /// - /// EventMap rid - /// A new instance - public abstract RidList GetEventRidList(uint eventMapRid); - - /// - /// Gets the Property rid list - /// - /// PropertyMap rid - /// A new instance - public abstract RidList GetPropertyRidList(uint propertyMapRid); - - /// - /// Finds all InterfaceImpl rids owned by - /// - /// Owner TypeDef rid - /// A instance containing the valid InterfaceImpl rids - public abstract RidList GetInterfaceImplRidList(uint typeDefRid); - - /// - /// Finds all GenericParam rids owned by in table - /// - /// A TypeOrMethodDef table - /// Owner rid - /// A instance containing the valid GenericParam rids - public abstract RidList GetGenericParamRidList(Table table, uint rid); - - /// - /// Finds all GenericParamConstraint rids owned by - /// - /// Owner GenericParam rid - /// A instance containing the valid GenericParamConstraint rids - public abstract RidList GetGenericParamConstraintRidList(uint genericParamRid); - - /// - /// Finds all CustomAttribute rids owned by in table - /// - /// A HasCustomAttribute table - /// Owner rid - /// A instance containing the valid CustomAttribute rids - public abstract RidList GetCustomAttributeRidList(Table table, uint rid); - - /// - /// Finds all DeclSecurity rids owned by in table - /// - /// A HasDeclSecurity table - /// Owner rid - /// A instance containing the valid DeclSecurity rids - public abstract RidList GetDeclSecurityRidList(Table table, uint rid); - - /// - /// Finds all MethodSemantics rids owned by in table - /// - /// A HasSemantic table - /// Owner rid - /// A instance containing the valid MethodSemantics rids - public abstract RidList GetMethodSemanticsRidList(Table table, uint rid); - - /// - /// Finds all MethodImpl rids owned by - /// - /// Owner TypeDef rid - /// A instance containing the valid MethodImpl rids - public abstract RidList GetMethodImplRidList(uint typeDefRid); - - /// - /// Finds a ClassLayout rid - /// - /// Owner TypeDef rid - /// The ClassLayout rid or 0 if is invalid - /// or if it has no row in the ClassLayout table. - public abstract uint GetClassLayoutRid(uint typeDefRid); - - /// - /// Finds a FieldLayout rid - /// - /// Owner Field rid - /// The FieldLayout rid or 0 if is invalid - /// or if it has no row in the FieldLayout table. - public abstract uint GetFieldLayoutRid(uint fieldRid); - - /// - /// Finds a FieldMarshal rid - /// - /// A HasFieldMarshal table - /// Owner rid - /// The FieldMarshal rid or 0 if is invalid - /// or if it has no row in the FieldMarshal table. - public abstract uint GetFieldMarshalRid(Table table, uint rid); - - /// - /// Finds a FieldRVA rid - /// - /// Owner Field rid - /// The FieldRVA rid or 0 if is invalid - /// or if it has no row in the FieldRVA table. - public abstract uint GetFieldRVARid(uint fieldRid); - - /// - /// Finds an ImplMap rid - /// - /// A MemberForwarded table - /// Owner rid - /// The ImplMap rid or 0 if is invalid - /// or if it has no row in the ImplMap table. - public abstract uint GetImplMapRid(Table table, uint rid); - - /// - /// Finds a NestedClass rid - /// - /// Owner TypeDef rid - /// The NestedClass rid or 0 if is invalid - /// or if it has no row in the NestedClass table. - public abstract uint GetNestedClassRid(uint typeDefRid); - - /// - /// Finds an EventMap rid - /// - /// Owner TypeDef rid - /// The EventMap rid or 0 if is invalid - /// or if it has no row in the EventMap table. - public abstract uint GetEventMapRid(uint typeDefRid); - - /// - /// Finds a PropertyMap rid - /// - /// Owner TypeDef rid - /// The PropertyMap rid or 0 if is invalid - /// or if it has no row in the PropertyMap table. - public abstract uint GetPropertyMapRid(uint typeDefRid); - - /// - /// Finds a Constant rid - /// - /// A HasConstant table - /// Owner rid - /// The Constant rid or 0 if is invalid - /// or if it has no row in the Constant table. - public abstract uint GetConstantRid(Table table, uint rid); - - /// - /// Returns the owner TypeDef rid - /// - /// A Field rid - /// The owner TypeDef rid or 0 if is invalid - /// or if it has no owner. - public abstract uint GetOwnerTypeOfField(uint fieldRid); - - /// - /// Returns the owner TypeDef rid - /// - /// A Method rid - /// The owner TypeDef rid or 0 if is invalid - /// or if it has no owner. - public abstract uint GetOwnerTypeOfMethod(uint methodRid); - - /// - /// Returns the owner TypeDef rid - /// - /// A Event rid - /// The owner TypeDef rid or 0 if is invalid - /// or if it has no owner. - public abstract uint GetOwnerTypeOfEvent(uint eventRid); - - /// - /// Returns the owner TypeDef rid - /// - /// A Property rid - /// The owner TypeDef rid or 0 if is invalid - /// or if it has no owner. - public abstract uint GetOwnerTypeOfProperty(uint propertyRid); - - /// - /// Returns the owner TypeOrMethodDef rid - /// - /// A GenericParam rid - /// The owner TypeOrMethodDef rid or 0 if is - /// invalid or if it has no owner. - public abstract uint GetOwnerOfGenericParam(uint gpRid); - - /// - /// Returns the owner GenericParam rid - /// - /// A GenericParamConstraint rid - /// The owner GenericParam rid or 0 if is - /// invalid or if it has no owner. - public abstract uint GetOwnerOfGenericParamConstraint(uint gpcRid); - - /// - /// Returns the owner Method rid - /// - /// A Param rid - /// The owner Method rid or 0 if is invalid - /// or if it has no owner. - public abstract uint GetOwnerOfParam(uint paramRid); - - /// - /// Gets a list of all nested classes owned by - /// - /// A TypeDef rid - /// A new instance - public abstract RidList GetNestedClassRidList(uint typeDefRid); - - /// - /// Gets a list of all non-nested classes. A type is a non-nested type if - /// returns an empty list. - /// - /// A new instance - public abstract RidList GetNonNestedClassRidList(); - - /// - /// Finds all LocalScope rids owned by - /// - /// Owner Method rid - /// 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 - /// - /// Owner Method rid - /// - public abstract uint GetStateMachineMethodRid(uint methodRid); - - /// - /// Finds all CustomDebugInformation rids owned by in table - /// - /// A HasCustomDebugInformation table - /// Owner rid - /// A instance containing the valid CustomDebugInformation rids - public abstract RidList GetCustomDebugInformationRidList(Table table, uint rid); - - /// - /// Disposes of this instance - /// - public abstract void Dispose(); - } -} diff --git a/Plugins/dnlib/DotNet/MD/MetadataBase.cs b/Plugins/dnlib/DotNet/MD/MetadataBase.cs deleted file mode 100644 index 9e6e115..0000000 --- a/Plugins/dnlib/DotNet/MD/MetadataBase.cs +++ /dev/null @@ -1,763 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using System.Threading; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.MD { - /// - /// Common base class for #~ and #- metadata classes - /// - abstract class MetadataBase : Metadata { - /// - /// The PE image - /// - protected IPEImage peImage; - - /// - /// The .NET header - /// - protected ImageCor20Header cor20Header; - - /// - /// The MD header - /// - protected MetadataHeader mdHeader; - - /// - /// The #Strings stream - /// - protected StringsStream stringsStream; - - /// - /// The #US stream - /// - protected USStream usStream; - - /// - /// The #Blob stream - /// - protected BlobStream blobStream; - - /// - /// The #GUID stream - /// - protected GuidStream guidStream; - - /// - /// The #~ or #- stream - /// - protected TablesStream tablesStream; - - /// - /// The #Pdb stream - /// - protected PdbStream pdbStream; - - /// - /// All the streams that are present in the PE image - /// - protected IList allStreams; - - public override bool IsStandalonePortablePdb => isStandalonePortablePdb; - /// true if this is standalone Portable PDB metadata - protected readonly bool isStandalonePortablePdb; - - uint[] fieldRidToTypeDefRid; - uint[] methodRidToTypeDefRid; - uint[] eventRidToTypeDefRid; - uint[] propertyRidToTypeDefRid; - uint[] gpRidToOwnerRid; - uint[] gpcRidToOwnerRid; - uint[] paramRidToOwnerRid; - Dictionary> typeDefRidToNestedClasses; - StrongBox nonNestedTypes; - - DataReaderFactory mdReaderFactoryToDisposeLater; - - /// - /// Sorts a table by key column - /// - protected sealed class SortedTable { - RowInfo[] rows; - - /// - /// Remembers rid and key - /// - [DebuggerDisplay("{rid} {key}")] - readonly struct RowInfo : IComparable { - public readonly uint rid; - public readonly uint key; - - /// - /// Constructor - /// - /// Row ID - /// Key - public RowInfo(uint rid, uint key) { - this.rid = rid; - this.key = key; - } - - public int CompareTo(RowInfo other) { - if (key < other.key) - return -1; - if (key > other.key) - return 1; - return rid.CompareTo(other.rid); - } - } - - /// - /// Constructor - /// - /// The MD table - /// Index of key column - public SortedTable(MDTable mdTable, int keyColIndex) { - InitializeKeys(mdTable, keyColIndex); - Array.Sort(rows); - } - - void InitializeKeys(MDTable mdTable, int keyColIndex) { - var keyColumn = mdTable.TableInfo.Columns[keyColIndex]; - Debug.Assert(keyColumn.Size == 2 || keyColumn.Size == 4); - rows = new RowInfo[mdTable.Rows + 1]; - if (mdTable.Rows == 0) - return; - var reader = mdTable.DataReader; - reader.Position = (uint)keyColumn.Offset; - uint increment = (uint)(mdTable.TableInfo.RowSize - keyColumn.Size); - for (uint i = 1; i <= mdTable.Rows; i++) { - rows[i] = new RowInfo(i, keyColumn.Unsafe_Read24(ref reader)); - if (i < mdTable.Rows) - reader.Position += increment; - } - } - - /// - /// Binary searches for a row with a certain key - /// - /// The key - /// The row or 0 if not found - int BinarySearch(uint key) { - int lo = 1, hi = rows.Length - 1; - while (lo <= hi && hi != -1) { - int curr = (lo + hi) / 2; - uint key2 = rows[curr].key; - if (key == key2) - return curr; - if (key2 > key) - hi = curr - 1; - else - lo = curr + 1; - } - - return 0; - } - - /// - /// Find all rids that contain - /// - /// The key - /// A new instance - public RidList FindAllRows(uint key) { - int startIndex = BinarySearch(key); - if (startIndex == 0) - return RidList.Empty; - int endIndex = startIndex + 1; - for (; startIndex > 1; startIndex--) { - if (key != rows[startIndex - 1].key) - break; - } - for (; endIndex < rows.Length; endIndex++) { - if (key != rows[endIndex].key) - break; - } - var list = new List(endIndex - startIndex); - for (int i = startIndex; i < endIndex; i++) - list.Add(rows[i].rid); - return RidList.Create(list); - } - } - SortedTable eventMapSortedTable; - SortedTable propertyMapSortedTable; - - public override ImageCor20Header ImageCor20Header => cor20Header; - public override uint Version => ((uint)mdHeader.MajorVersion << 16) | mdHeader.MinorVersion; - public override string VersionString => mdHeader.VersionString; - public override IPEImage PEImage => peImage; - public override MetadataHeader MetadataHeader => mdHeader; - public override StringsStream StringsStream => stringsStream; - public override USStream USStream => usStream; - public override BlobStream BlobStream => blobStream; - public override GuidStream GuidStream => guidStream; - public override TablesStream TablesStream => tablesStream; - public override PdbStream PdbStream => pdbStream; - public override IList AllStreams => allStreams; - - /// - /// Constructor - /// - /// The PE image - /// The .NET header - /// The MD header - protected MetadataBase(IPEImage peImage, ImageCor20Header cor20Header, MetadataHeader mdHeader) { - try { - allStreams = new List(); - this.peImage = peImage; - this.cor20Header = cor20Header; - this.mdHeader = mdHeader; - isStandalonePortablePdb = false; - } - catch { - if (peImage is not null) - peImage.Dispose(); - throw; - } - } - - internal MetadataBase(MetadataHeader mdHeader, bool isStandalonePortablePdb) { - allStreams = new List(); - peImage = null; - cor20Header = null; - this.mdHeader = mdHeader; - this.isStandalonePortablePdb = isStandalonePortablePdb; - } - - /// - /// Initializes the metadata, tables, streams - /// - public void Initialize(DataReaderFactory mdReaderFactory) { - mdReaderFactoryToDisposeLater = mdReaderFactory; - uint metadataBaseOffset; - if (peImage is not null) { - Debug.Assert(mdReaderFactory is null); - Debug.Assert(cor20Header is not null); - metadataBaseOffset = (uint)peImage.ToFileOffset(cor20Header.Metadata.VirtualAddress); - mdReaderFactory = peImage.DataReaderFactory; - } - else { - Debug.Assert(mdReaderFactory is not null); - metadataBaseOffset = 0; - } - InitializeInternal(mdReaderFactory, metadataBaseOffset); - - if (tablesStream is null) - throw new BadImageFormatException("Missing MD stream"); - if (isStandalonePortablePdb && pdbStream is null) - throw new BadImageFormatException("Missing #Pdb stream"); - InitializeNonExistentHeaps(); - } - - /// - /// Creates empty heap objects if they're not present in the metadata - /// - protected void InitializeNonExistentHeaps() { - if (stringsStream is null) - stringsStream = new StringsStream(); - if (usStream is null) - usStream = new USStream(); - if (blobStream is null) - blobStream = new BlobStream(); - if (guidStream is null) - guidStream = new GuidStream(); - } - - /// - /// Called by - /// - protected abstract void InitializeInternal(DataReaderFactory mdReaderFactory, uint metadataBaseOffset); - - public override RidList GetTypeDefRidList() => RidList.Create(1, tablesStream.TypeDefTable.Rows); - public override RidList GetExportedTypeRidList() => RidList.Create(1, tablesStream.ExportedTypeTable.Rows); - - /// - /// Binary searches the table 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 - protected abstract uint BinarySearch(MDTable tableSource, int keyColIndex, uint key); - - /// - /// Finds all rows owned by in table - /// whose index is - /// - /// Table to search - /// Key column index - /// Key - /// A instance - protected RidList FindAllRows(MDTable tableSource, int keyColIndex, uint key) { - uint startRid = BinarySearch(tableSource, keyColIndex, key); - if (tableSource.IsInvalidRID(startRid)) - return RidList.Empty; - uint endRid = startRid + 1; - var column = tableSource.TableInfo.Columns[keyColIndex]; - for (; startRid > 1; startRid--) { - if (!tablesStream.TryReadColumn24(tableSource, startRid - 1, column, out uint key2)) - break; // Should never happen since startRid is valid - if (key != key2) - break; - } - for (; endRid <= tableSource.Rows; endRid++) { - if (!tablesStream.TryReadColumn24(tableSource, endRid, column, out uint key2)) - break; // Should never happen since endRid is valid - if (key != key2) - break; - } - return RidList.Create(startRid, endRid - startRid); - } - - /// - /// Finds all rows owned by in table - /// whose index is . Should be called if - /// could be unsorted. - /// - /// Table to search - /// Key column index - /// Key - /// A instance - protected virtual RidList FindAllRowsUnsorted(MDTable tableSource, int keyColIndex, uint key) => FindAllRows(tableSource, keyColIndex, key); - - public override RidList GetInterfaceImplRidList(uint typeDefRid) => FindAllRowsUnsorted(tablesStream.InterfaceImplTable, 0, typeDefRid); - - public override RidList GetGenericParamRidList(Table table, uint rid) { - if (!CodedToken.TypeOrMethodDef.Encode(new MDToken(table, rid), out uint codedToken)) - return RidList.Empty; - return FindAllRowsUnsorted(tablesStream.GenericParamTable, 2, codedToken); - } - - public override RidList GetGenericParamConstraintRidList(uint genericParamRid) => - FindAllRowsUnsorted(tablesStream.GenericParamConstraintTable, 0, genericParamRid); - - public override RidList GetCustomAttributeRidList(Table table, uint rid) { - if (!CodedToken.HasCustomAttribute.Encode(new MDToken(table, rid), out uint codedToken)) - return RidList.Empty; - return FindAllRowsUnsorted(tablesStream.CustomAttributeTable, 0, codedToken); - } - - public override RidList GetDeclSecurityRidList(Table table, uint rid) { - if (!CodedToken.HasDeclSecurity.Encode(new MDToken(table, rid), out uint codedToken)) - return RidList.Empty; - return FindAllRowsUnsorted(tablesStream.DeclSecurityTable, 1, codedToken); - } - - public override RidList GetMethodSemanticsRidList(Table table, uint rid) { - if (!CodedToken.HasSemantic.Encode(new MDToken(table, rid), out uint codedToken)) - return RidList.Empty; - return FindAllRowsUnsorted(tablesStream.MethodSemanticsTable, 2, codedToken); - } - - public override RidList GetMethodImplRidList(uint typeDefRid) => FindAllRowsUnsorted(tablesStream.MethodImplTable, 0, typeDefRid); - - public override uint GetClassLayoutRid(uint typeDefRid) { - var list = FindAllRowsUnsorted(tablesStream.ClassLayoutTable, 2, typeDefRid); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetFieldLayoutRid(uint fieldRid) { - var list = FindAllRowsUnsorted(tablesStream.FieldLayoutTable, 1, fieldRid); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetFieldMarshalRid(Table table, uint rid) { - if (!CodedToken.HasFieldMarshal.Encode(new MDToken(table, rid), out uint codedToken)) - return 0; - var list = FindAllRowsUnsorted(tablesStream.FieldMarshalTable, 0, codedToken); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetFieldRVARid(uint fieldRid) { - var list = FindAllRowsUnsorted(tablesStream.FieldRVATable, 1, fieldRid); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetImplMapRid(Table table, uint rid) { - if (!CodedToken.MemberForwarded.Encode(new MDToken(table, rid), out uint codedToken)) - return 0; - var list = FindAllRowsUnsorted(tablesStream.ImplMapTable, 1, codedToken); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetNestedClassRid(uint typeDefRid) { - var list = FindAllRowsUnsorted(tablesStream.NestedClassTable, 0, typeDefRid); - return list.Count == 0 ? 0 : list[0]; - } - - 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 is null) - Interlocked.CompareExchange(ref eventMapSortedTable, new SortedTable(tablesStream.EventMapTable, 0), null); - var list = eventMapSortedTable.FindAllRows(typeDefRid); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetPropertyMapRid(uint typeDefRid) { - // Always unsorted, see comment in GetEventMapRid() above - 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]; - } - - public override uint GetConstantRid(Table table, uint rid) { - if (!CodedToken.HasConstant.Encode(new MDToken(table, rid), out uint codedToken)) - return 0; - var list = FindAllRowsUnsorted(tablesStream.ConstantTable, 2, codedToken); - return list.Count == 0 ? 0 : list[0]; - } - - public override uint GetOwnerTypeOfField(uint fieldRid) { - if (fieldRidToTypeDefRid is null) - InitializeInverseFieldOwnerRidList(); - uint index = fieldRid - 1; - if (index >= fieldRidToTypeDefRid.LongLength) - return 0; - return fieldRidToTypeDefRid[index]; - } - - void InitializeInverseFieldOwnerRidList() { - if (fieldRidToTypeDefRid is not null) - return; - var newFieldRidToTypeDefRid = new uint[tablesStream.FieldTable.Rows]; - var ownerList = GetTypeDefRidList(); - for (int i = 0; i < ownerList.Count; i++) { - var ownerRid = ownerList[i]; - var fieldList = GetFieldRidList(ownerRid); - for (int j = 0; j < fieldList.Count; j++) { - uint ridIndex = fieldList[j] - 1; - if (newFieldRidToTypeDefRid[ridIndex] != 0) - continue; - newFieldRidToTypeDefRid[ridIndex] = ownerRid; - } - } - Interlocked.CompareExchange(ref fieldRidToTypeDefRid, newFieldRidToTypeDefRid, null); - } - - public override uint GetOwnerTypeOfMethod(uint methodRid) { - if (methodRidToTypeDefRid is null) - InitializeInverseMethodOwnerRidList(); - uint index = methodRid - 1; - if (index >= methodRidToTypeDefRid.LongLength) - return 0; - return methodRidToTypeDefRid[index]; - } - - void InitializeInverseMethodOwnerRidList() { - if (methodRidToTypeDefRid is not null) - return; - var newMethodRidToTypeDefRid = new uint[tablesStream.MethodTable.Rows]; - var ownerList = GetTypeDefRidList(); - for (int i = 0; i < ownerList.Count; i++) { - var ownerRid = ownerList[i]; - var methodList = GetMethodRidList(ownerRid); - for (int j = 0; j < methodList.Count; j++) { - uint ridIndex = methodList[j] - 1; - if (newMethodRidToTypeDefRid[ridIndex] != 0) - continue; - newMethodRidToTypeDefRid[ridIndex] = ownerRid; - } - } - Interlocked.CompareExchange(ref methodRidToTypeDefRid, newMethodRidToTypeDefRid, null); - } - - public override uint GetOwnerTypeOfEvent(uint eventRid) { - if (eventRidToTypeDefRid is null) - InitializeInverseEventOwnerRidList(); - uint index = eventRid - 1; - if (index >= eventRidToTypeDefRid.LongLength) - return 0; - return eventRidToTypeDefRid[index]; - } - - void InitializeInverseEventOwnerRidList() { - if (eventRidToTypeDefRid is not null) - return; - var newEventRidToTypeDefRid = new uint[tablesStream.EventTable.Rows]; - var ownerList = GetTypeDefRidList(); - for (int i = 0; i < ownerList.Count; i++) { - var ownerRid = ownerList[i]; - var eventList = GetEventRidList(GetEventMapRid(ownerRid)); - for (int j = 0; j < eventList.Count; j++) { - uint ridIndex = eventList[j] - 1; - if (newEventRidToTypeDefRid[ridIndex] != 0) - continue; - newEventRidToTypeDefRid[ridIndex] = ownerRid; - } - } - Interlocked.CompareExchange(ref eventRidToTypeDefRid, newEventRidToTypeDefRid, null); - } - - public override uint GetOwnerTypeOfProperty(uint propertyRid) { - if (propertyRidToTypeDefRid is null) - InitializeInversePropertyOwnerRidList(); - uint index = propertyRid - 1; - if (index >= propertyRidToTypeDefRid.LongLength) - return 0; - return propertyRidToTypeDefRid[index]; - } - - void InitializeInversePropertyOwnerRidList() { - if (propertyRidToTypeDefRid is not null) - return; - var newPropertyRidToTypeDefRid = new uint[tablesStream.PropertyTable.Rows]; - var ownerList = GetTypeDefRidList(); - for (int i = 0; i < ownerList.Count; i++) { - var ownerRid = ownerList[i]; - var propertyList = GetPropertyRidList(GetPropertyMapRid(ownerRid)); - for (int j = 0; j < propertyList.Count; j++) { - uint ridIndex = propertyList[j] - 1; - if (newPropertyRidToTypeDefRid[ridIndex] != 0) - continue; - newPropertyRidToTypeDefRid[ridIndex] = ownerRid; - } - } - Interlocked.CompareExchange(ref propertyRidToTypeDefRid, newPropertyRidToTypeDefRid, null); - } - - public override uint GetOwnerOfGenericParam(uint gpRid) { - // Don't use GenericParam.Owner column. If the GP table is sorted, it's - // possible to have two blocks of GPs with the same owner. Only one of the - // blocks is the "real" generic params for the owner. Of course, rarely - // if ever will this occur, but could happen if some obfuscator has - // added it. - - if (gpRidToOwnerRid is null) - InitializeInverseGenericParamOwnerRidList(); - uint index = gpRid - 1; - if (index >= gpRidToOwnerRid.LongLength) - return 0; - return gpRidToOwnerRid[index]; - } - - void InitializeInverseGenericParamOwnerRidList() { - if (gpRidToOwnerRid is not null) - return; - var gpTable = tablesStream.GenericParamTable; - var newGpRidToOwnerRid = new uint[gpTable.Rows]; - - // Find all owners by reading the GenericParam.Owner column - var ownerCol = gpTable.TableInfo.Columns[2]; - var ownersDict = new Dictionary(); - for (uint rid = 1; rid <= gpTable.Rows; rid++) { - if (!tablesStream.TryReadColumn24(gpTable, rid, ownerCol, out uint owner)) - continue; - ownersDict[owner] = true; - } - - // Now that we have the owners, find all the generic params they own. An obfuscated - // module could have 2+ owners pointing to the same generic param row. - var owners = new List(ownersDict.Keys); - owners.Sort(); - for (int i = 0; i < owners.Count; i++) { - if (!CodedToken.TypeOrMethodDef.Decode(owners[i], out uint ownerToken)) - continue; - var ridList = GetGenericParamRidList(MDToken.ToTable(ownerToken), MDToken.ToRID(ownerToken)); - for (int j = 0; j < ridList.Count; j++) { - uint ridIndex = ridList[j] - 1; - if (newGpRidToOwnerRid[ridIndex] != 0) - continue; - newGpRidToOwnerRid[ridIndex] = owners[i]; - } - } - Interlocked.CompareExchange(ref gpRidToOwnerRid, newGpRidToOwnerRid, null); - } - - public override uint GetOwnerOfGenericParamConstraint(uint gpcRid) { - // Don't use GenericParamConstraint.Owner column for the same reason - // as described in GetOwnerOfGenericParam(). - - if (gpcRidToOwnerRid is null) - InitializeInverseGenericParamConstraintOwnerRidList(); - uint index = gpcRid - 1; - if (index >= gpcRidToOwnerRid.LongLength) - return 0; - return gpcRidToOwnerRid[index]; - } - - void InitializeInverseGenericParamConstraintOwnerRidList() { - if (gpcRidToOwnerRid is not null) - return; - var gpcTable = tablesStream.GenericParamConstraintTable; - var newGpcRidToOwnerRid = new uint[gpcTable.Rows]; - - var ownerCol = gpcTable.TableInfo.Columns[0]; - var ownersDict = new Dictionary(); - for (uint rid = 1; rid <= gpcTable.Rows; rid++) { - if (!tablesStream.TryReadColumn24(gpcTable, rid, ownerCol, out uint owner)) - continue; - ownersDict[owner] = true; - } - - var owners = new List(ownersDict.Keys); - owners.Sort(); - for (int i = 0; i < owners.Count; i++) { - uint ownerToken = owners[i]; - var ridList = GetGenericParamConstraintRidList(ownerToken); - for (int j = 0; j < ridList.Count; j++) { - uint ridIndex = ridList[j] - 1; - if (newGpcRidToOwnerRid[ridIndex] != 0) - continue; - newGpcRidToOwnerRid[ridIndex] = ownerToken; - } - } - Interlocked.CompareExchange(ref gpcRidToOwnerRid, newGpcRidToOwnerRid, null); - } - - public override uint GetOwnerOfParam(uint paramRid) { - if (paramRidToOwnerRid is null) - InitializeInverseParamOwnerRidList(); - uint index = paramRid - 1; - if (index >= paramRidToOwnerRid.LongLength) - return 0; - return paramRidToOwnerRid[index]; - } - - void InitializeInverseParamOwnerRidList() { - if (paramRidToOwnerRid is not null) - return; - - var newParamRidToOwnerRid = new uint[tablesStream.ParamTable.Rows]; - var table = tablesStream.MethodTable; - for (uint rid = 1; rid <= table.Rows; rid++) { - var ridList = GetParamRidList(rid); - for (int j = 0; j < ridList.Count; j++) { - uint ridIndex = ridList[j] - 1; - if (newParamRidToOwnerRid[ridIndex] != 0) - continue; - newParamRidToOwnerRid[ridIndex] = rid; - } - } - Interlocked.CompareExchange(ref paramRidToOwnerRid, newParamRidToOwnerRid, null); - } - - public override RidList GetNestedClassRidList(uint typeDefRid) { - if (typeDefRidToNestedClasses is null) - InitializeNestedClassesDictionary(); - if (typeDefRidToNestedClasses.TryGetValue(typeDefRid, out var ridList)) - return RidList.Create(ridList); - return RidList.Empty; - } - - void InitializeNestedClassesDictionary() { - var table = tablesStream.NestedClassTable; - var destTable = tablesStream.TypeDefTable; - - Dictionary validTypeDefRids = null; - var typeDefRidList = GetTypeDefRidList(); - if ((uint)typeDefRidList.Count != destTable.Rows) { - validTypeDefRids = new Dictionary(typeDefRidList.Count); - for (int i = 0; i < typeDefRidList.Count; i++) - validTypeDefRids[typeDefRidList[i]] = true; - } - - 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 not null && !validTypeDefRids.ContainsKey(rid)) - continue; - if (!tablesStream.TryReadNestedClassRow(rid, out var row)) - continue; // Should never happen since rid is valid - if (!destTable.IsValidRID(row.NestedClass) || !destTable.IsValidRID(row.EnclosingClass)) - continue; - if (nestedRidsDict.ContainsKey(row.NestedClass)) - continue; - nestedRidsDict[row.NestedClass] = true; - nestedRids.Add(row.NestedClass); - } - - var newTypeDefRidToNestedClasses = new Dictionary>(); - 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)) - newTypeDefRidToNestedClasses[row.EnclosingClass] = ridList = new List(); - ridList.Add(nestedRid); - } - - var newNonNestedTypes = new List((int)(destTable.Rows - nestedRidsDict.Count)); - for (uint rid = 1; rid <= destTable.Rows; rid++) { - if (validTypeDefRids is not null && !validTypeDefRids.ContainsKey(rid)) - continue; - if (nestedRidsDict.ContainsKey(rid)) - continue; - newNonNestedTypes.Add(rid); - } - - Interlocked.CompareExchange(ref nonNestedTypes, new StrongBox(RidList.Create(newNonNestedTypes)), null); - - // Initialize this one last since it's tested by the callers of this method - Interlocked.CompareExchange(ref typeDefRidToNestedClasses, newTypeDefRidToNestedClasses, null); - } - - public override RidList GetNonNestedClassRidList() { - // Check typeDefRidToNestedClasses and not nonNestedTypes since - // InitializeNestedClassesDictionary() writes to typeDefRidToNestedClasses last. - if (typeDefRidToNestedClasses is null) - InitializeNestedClassesDictionary(); - return nonNestedTypes.Value; - } - - public override RidList GetLocalScopeRidList(uint methodRid) => FindAllRows(tablesStream.LocalScopeTable, 0, methodRid); - - public override uint GetStateMachineMethodRid(uint methodRid) { - var list = FindAllRows(tablesStream.StateMachineMethodTable, 0, methodRid); - return list.Count == 0 ? 0 : list[0]; - } - - public override RidList GetCustomDebugInformationRidList(Table table, uint rid) { - if (!CodedToken.HasCustomDebugInformation.Encode(new MDToken(table, rid), out uint codedToken)) - return RidList.Empty; - return FindAllRows(tablesStream.CustomDebugInformationTable, 0, codedToken); - } - - public override void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose method - /// - /// true if called by - protected virtual void Dispose(bool disposing) { - if (!disposing) - return; - peImage?.Dispose(); - stringsStream?.Dispose(); - usStream?.Dispose(); - blobStream?.Dispose(); - guidStream?.Dispose(); - tablesStream?.Dispose(); - var as2 = allStreams; - if (as2 is not null) { - foreach (var stream in as2) - stream?.Dispose(); - } - mdReaderFactoryToDisposeLater?.Dispose(); - peImage = null; - cor20Header = null; - mdHeader = null; - stringsStream = null; - usStream = null; - blobStream = null; - guidStream = null; - tablesStream = null; - allStreams = null; - fieldRidToTypeDefRid = null; - methodRidToTypeDefRid = null; - typeDefRidToNestedClasses = null; - mdReaderFactoryToDisposeLater = null; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/MetadataFactory.cs b/Plugins/dnlib/DotNet/MD/MetadataFactory.cs deleted file mode 100644 index 1904ed9..0000000 --- a/Plugins/dnlib/DotNet/MD/MetadataFactory.cs +++ /dev/null @@ -1,222 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.MD { - /// - /// Low level access to a .NET file's metadata - /// - public static class MetadataFactory { - enum MetadataType { - Unknown, - Compressed, // #~ (normal) - ENC, // #- (edit and continue) - } - - internal static MetadataBase Load(string fileName, CLRRuntimeReaderKind runtime) { - IPEImage peImage = null; - try { - return Load(peImage = new PEImage(fileName), runtime); - } - catch { - if (peImage is not null) - peImage.Dispose(); - throw; - } - } - - internal static MetadataBase Load(byte[] data, CLRRuntimeReaderKind runtime) { - IPEImage peImage = null; - try { - return Load(peImage = new PEImage(data), runtime); - } - catch { - if (peImage is not null) - peImage.Dispose(); - throw; - } - } - - 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), runtime); - } - catch { - if (peImage is not null) - peImage.Dispose(); - peImage = null; - } - - try { - return Load(peImage = new PEImage(addr, ImageLayout.File, true), runtime); - } - catch { - if (peImage is not null) - peImage.Dispose(); - throw; - } - } - - internal static MetadataBase Load(IntPtr addr, ImageLayout imageLayout, CLRRuntimeReaderKind runtime) { - IPEImage peImage = null; - try { - return Load(peImage = new PEImage(addr, imageLayout, true), runtime); - } - catch { - if (peImage is not null) - peImage.Dispose(); - throw; - } - } - - internal static MetadataBase Load(IPEImage peImage, CLRRuntimeReaderKind runtime) => Create(peImage, runtime, true); - - /// - /// Create a instance - /// - /// The PE image - /// 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, 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, 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, CLRRuntimeReaderKind runtime, 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"); - var cor20HeaderReader = peImage.CreateReader(dotNetDir.VirtualAddress, 0x48); - 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, runtime, verify); - if (verify) { - foreach (var sh in mdHeader.StreamHeaders) { - if ((ulong)sh.Offset + sh.StreamSize > mdHeaderReader.EndOffset) - throw new BadImageFormatException("Invalid stream header"); - } - } - - 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; - } - catch { - if (md is not null) - md.Dispose(); - throw; - } - } - - /// - /// 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 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, runtime, verify); - if (verify) { - foreach (var sh in mdHeader.StreamHeaders) { - if (sh.Offset + sh.StreamSize < sh.Offset || sh.Offset + sh.StreamSize > reader.Length) - throw new BadImageFormatException("Invalid stream header"); - } - } - - 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; - } - catch { - md?.Dispose(); - throw; - } - } - - static MetadataType GetMetadataType(IList streamHeaders, CLRRuntimeReaderKind runtime) { - MetadataType? mdType = 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; - break; - } - } - } - else - throw new ArgumentOutOfRangeException(nameof(runtime)); - if (mdType is null) - return MetadataType.Unknown; - return mdType.Value; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/MetadataHeader.cs b/Plugins/dnlib/DotNet/MD/MetadataHeader.cs deleted file mode 100644 index 69604af..0000000 --- a/Plugins/dnlib/DotNet/MD/MetadataHeader.cs +++ /dev/null @@ -1,141 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Text; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Represents the .NET metadata header - /// - /// IMAGE_COR20_HEADER.Metadata points to this header - public sealed class MetadataHeader : FileSection { - readonly uint signature; - readonly ushort majorVersion; - readonly ushort minorVersion; - readonly uint reserved1; - readonly uint stringLength; - readonly string versionString; - readonly FileOffset offset2ndPart; - readonly StorageFlags flags; - readonly byte reserved2; - readonly ushort streams; - readonly IList streamHeaders; - - /// - /// Returns the signature (should be 0x424A5342) - /// - public uint Signature => signature; - - /// - /// Returns the major version - /// - public ushort MajorVersion => majorVersion; - - /// - /// Returns the minor version - /// - public ushort MinorVersion => minorVersion; - - /// - /// Returns the reserved dword (pointer to extra header data) - /// - public uint Reserved1 => reserved1; - - /// - /// Returns the version string length value - /// - public uint StringLength => stringLength; - - /// - /// Returns the version string - /// - public string VersionString => versionString; - - /// - /// Returns the offset of STORAGEHEADER - /// - public FileOffset StorageHeaderOffset => offset2ndPart; - - /// - /// Returns the flags (reserved) - /// - public StorageFlags Flags => flags; - - /// - /// Returns the reserved byte (padding) - /// - public byte Reserved2 => reserved2; - - /// - /// Returns the number of streams - /// - public ushort Streams => streams; - - /// - /// Returns all stream headers - /// - public IList StreamHeaders => streamHeaders; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - 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) - throw new BadImageFormatException("Invalid metadata header signature"); - majorVersion = reader.ReadUInt16(); - minorVersion = reader.ReadUInt16(); - reserved1 = reader.ReadUInt32(); - stringLength = reader.ReadUInt32(); - versionString = ReadString(ref reader, stringLength, runtime); - offset2ndPart = (FileOffset)reader.CurrentOffset; - flags = (StorageFlags)reader.ReadByte(); - reserved2 = reader.ReadByte(); - streams = reader.ReadUInt16(); - 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, runtime, out bool failedVerification); - if (failedVerification || (ulong)sh.Offset + sh.StreamSize > reader.EndOffset) - sh = new StreamHeader(0, 0, ""); - streamHeaders[i] = sh; - } - SetEndoffset(ref reader); - } - - 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; - for (i = 0; i < maxLength; i++) { - byte b = reader.ReadByte(); - if (b == 0) - break; - utf8Bytes[i] = b; - } - reader.CurrentOffset = (uint)endOffset; - return Encoding.UTF8.GetString(utf8Bytes, 0, (int)i); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/PdbStream.cs b/Plugins/dnlib/DotNet/MD/PdbStream.cs deleted file mode 100644 index d5734ae..0000000 --- a/Plugins/dnlib/DotNet/MD/PdbStream.cs +++ /dev/null @@ -1,46 +0,0 @@ -// 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(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - var reader = CreateReader(); - Id = reader.ReadBytes(20); - EntryPoint = new MDToken(reader.ReadUInt32()); - var tables = reader.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] = reader.ReadUInt32(); - } - TypeSystemTableRows = rows; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/RawRowEqualityComparer.cs b/Plugins/dnlib/DotNet/MD/RawRowEqualityComparer.cs deleted file mode 100644 index cf82453..0000000 --- a/Plugins/dnlib/DotNet/MD/RawRowEqualityComparer.cs +++ /dev/null @@ -1,550 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -#pragma warning disable 1591 // XML doc comments - -namespace dnlib.DotNet.MD { - /// - /// Equality comparer for all raw rows - /// - public sealed class RawRowEqualityComparer : IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer, - IEqualityComparer, IEqualityComparer { - - /// - /// Default instance - /// - public static readonly RawRowEqualityComparer Instance = new RawRowEqualityComparer(); - - 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/Plugins/dnlib/DotNet/MD/RawTableRows.cs b/Plugins/dnlib/DotNet/MD/RawTableRows.cs deleted file mode 100644 index 6092457..0000000 --- a/Plugins/dnlib/DotNet/MD/RawTableRows.cs +++ /dev/null @@ -1,1468 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -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 - /// - public readonly struct RawModuleRow { - public readonly ushort Generation; - public readonly uint Name; - public readonly uint Mvid; - public readonly uint EncId; - public readonly uint EncBaseId; - - public RawModuleRow(ushort Generation, uint Name, uint Mvid, uint EncId, uint EncBaseId) { - this.Generation = Generation; - this.Name = Name; - this.Mvid = Mvid; - this.EncId = EncId; - this.EncBaseId = EncBaseId; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Generation, - 1 => Name, - 2 => Mvid, - 3 => EncId, - 4 => EncBaseId, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed TypeRef table row - /// - public readonly struct RawTypeRefRow { - public readonly uint ResolutionScope; - public readonly uint Name; - public readonly uint Namespace; - - public RawTypeRefRow(uint ResolutionScope, uint Name, uint Namespace) { - this.ResolutionScope = ResolutionScope; - this.Name = Name; - this.Namespace = Namespace; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => ResolutionScope, - 1 => Name, - 2 => Namespace, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed TypeDef table row - /// - public readonly struct RawTypeDefRow { - public readonly uint Flags; - public readonly uint Name; - public readonly uint Namespace; - public readonly uint Extends; - public readonly uint FieldList; - public readonly uint MethodList; - - public RawTypeDefRow(uint Flags, uint Name, uint Namespace, uint Extends, uint FieldList, uint MethodList) { - this.Flags = Flags; - this.Name = Name; - this.Namespace = Namespace; - this.Extends = Extends; - this.FieldList = FieldList; - this.MethodList = MethodList; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Flags, - 1 => Name, - 2 => Namespace, - 3 => Extends, - 4 => FieldList, - 5 => MethodList, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed FieldPtr table row - /// - public readonly struct RawFieldPtrRow { - public readonly uint Field; - - public RawFieldPtrRow(uint Field) => this.Field = Field; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Field, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Field table row - /// - public readonly struct RawFieldRow { - public readonly ushort Flags; - public readonly uint Name; - public readonly uint Signature; - - public RawFieldRow(ushort Flags, uint Name, uint Signature) { - this.Flags = Flags; - this.Name = Name; - this.Signature = Signature; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Flags, - 1 => Name, - 2 => Signature, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MethodPtr table row - /// - public readonly struct RawMethodPtrRow { - public readonly uint Method; - - public RawMethodPtrRow(uint Method) => this.Method = Method; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Method, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Method table row - /// - public readonly struct RawMethodRow { - public readonly uint RVA; - public readonly ushort ImplFlags; - public readonly ushort Flags; - public readonly uint Name; - public readonly uint Signature; - public readonly uint ParamList; - - public RawMethodRow(uint RVA, ushort ImplFlags, ushort Flags, uint Name, uint Signature, uint ParamList) { - this.RVA = RVA; - this.ImplFlags = ImplFlags; - this.Flags = Flags; - this.Name = Name; - this.Signature = Signature; - this.ParamList = ParamList; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => RVA, - 1 => ImplFlags, - 2 => Flags, - 3 => Name, - 4 => Signature, - 5 => ParamList, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ParamPtr table row - /// - public readonly struct RawParamPtrRow { - public readonly uint Param; - - public RawParamPtrRow(uint Param) => this.Param = Param; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Param, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Param table row - /// - public readonly struct RawParamRow { - public readonly ushort Flags; - public readonly ushort Sequence; - public readonly uint Name; - - public RawParamRow(ushort Flags, ushort Sequence, uint Name) { - this.Flags = Flags; - this.Sequence = Sequence; - this.Name = Name; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Flags, - 1 => Sequence, - 2 => Name, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed InterfaceImpl table row - /// - public readonly struct RawInterfaceImplRow { - public readonly uint Class; - public readonly uint Interface; - - public RawInterfaceImplRow(uint Class, uint Interface) { - this.Class = Class; - this.Interface = Interface; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Class, - 1 => Interface, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MemberRef table row - /// - public readonly struct RawMemberRefRow { - public readonly uint Class; - public readonly uint Name; - public readonly uint Signature; - - public RawMemberRefRow(uint Class, uint Name, uint Signature) { - this.Class = Class; - this.Name = Name; - this.Signature = Signature; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Class, - 1 => Name, - 2 => Signature, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Constant table row - /// - public readonly struct RawConstantRow { - public readonly byte Type; - public readonly byte Padding; - public readonly uint Parent; - public readonly uint Value; - - public RawConstantRow(byte Type, byte Padding, uint Parent, uint Value) { - this.Type = Type; - this.Padding = Padding; - this.Parent = Parent; - this.Value = Value; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Type, - 1 => Padding, - 2 => Parent, - 3 => Value, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed CustomAttribute table row - /// - public readonly struct RawCustomAttributeRow { - public readonly uint Parent; - public readonly uint Type; - public readonly uint Value; - - public RawCustomAttributeRow(uint Parent, uint Type, uint Value) { - this.Parent = Parent; - this.Type = Type; - this.Value = Value; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Parent, - 1 => Type, - 2 => Value, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed FieldMarshal table row - /// - public readonly struct RawFieldMarshalRow { - public readonly uint Parent; - public readonly uint NativeType; - - public RawFieldMarshalRow(uint Parent, uint NativeType) { - this.Parent = Parent; - this.NativeType = NativeType; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Parent, - 1 => NativeType, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed DeclSecurity table row - /// - public readonly struct RawDeclSecurityRow { - public readonly short Action; - public readonly uint Parent; - public readonly uint PermissionSet; - - public RawDeclSecurityRow(short Action, uint Parent, uint PermissionSet) { - this.Action = Action; - this.Parent = Parent; - this.PermissionSet = PermissionSet; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => (uint)(int)Action, - 1 => Parent, - 2 => PermissionSet, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ClassLayout table row - /// - public readonly struct RawClassLayoutRow { - public readonly ushort PackingSize; - public readonly uint ClassSize; - public readonly uint Parent; - - public RawClassLayoutRow(ushort PackingSize, uint ClassSize, uint Parent) { - this.PackingSize = PackingSize; - this.ClassSize = ClassSize; - this.Parent = Parent; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => PackingSize, - 1 => ClassSize, - 2 => Parent, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed FieldLayout table row - /// - public readonly struct RawFieldLayoutRow { - public readonly uint OffSet; - public readonly uint Field; - - public RawFieldLayoutRow(uint OffSet, uint Field) { - this.OffSet = OffSet; - this.Field = Field; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => OffSet, - 1 => Field, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed StandAloneSig table row - /// - public readonly struct RawStandAloneSigRow { - public readonly uint Signature; - - public RawStandAloneSigRow(uint Signature) => this.Signature = Signature; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Signature, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed EventMap table row - /// - public readonly struct RawEventMapRow { - public readonly uint Parent; - public readonly uint EventList; - - public RawEventMapRow(uint Parent, uint EventList) { - this.Parent = Parent; - this.EventList = EventList; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Parent, - 1 => EventList, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed EventPtr table row - /// - public readonly struct RawEventPtrRow { - public readonly uint Event; - - public RawEventPtrRow(uint Event) => this.Event = Event; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Event, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Event table row - /// - public readonly struct RawEventRow { - public readonly ushort EventFlags; - public readonly uint Name; - public readonly uint EventType; - - public RawEventRow(ushort EventFlags, uint Name, uint EventType) { - this.EventFlags = EventFlags; - this.Name = Name; - this.EventType = EventType; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => EventFlags, - 1 => Name, - 2 => EventType, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed PropertyMap table row - /// - public readonly struct RawPropertyMapRow { - public readonly uint Parent; - public readonly uint PropertyList; - - public RawPropertyMapRow(uint Parent, uint PropertyList) { - this.Parent = Parent; - this.PropertyList = PropertyList; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Parent, - 1 => PropertyList, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed PropertyPtr table row - /// - public readonly struct RawPropertyPtrRow { - public readonly uint Property; - - public RawPropertyPtrRow(uint Property) => this.Property = Property; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Property, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Property table row - /// - public readonly struct RawPropertyRow { - public readonly ushort PropFlags; - public readonly uint Name; - public readonly uint Type; - - public RawPropertyRow(ushort PropFlags, uint Name, uint Type) { - this.PropFlags = PropFlags; - this.Name = Name; - this.Type = Type; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => PropFlags, - 1 => Name, - 2 => Type, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MethodSemantics table row - /// - public readonly struct RawMethodSemanticsRow { - public readonly ushort Semantic; - public readonly uint Method; - public readonly uint Association; - - public RawMethodSemanticsRow(ushort Semantic, uint Method, uint Association) { - this.Semantic = Semantic; - this.Method = Method; - this.Association = Association; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Semantic, - 1 => Method, - 2 => Association, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MethodImpl table row - /// - public readonly struct RawMethodImplRow { - public readonly uint Class; - public readonly uint MethodBody; - public readonly uint MethodDeclaration; - - public RawMethodImplRow(uint Class, uint MethodBody, uint MethodDeclaration) { - this.Class = Class; - this.MethodBody = MethodBody; - this.MethodDeclaration = MethodDeclaration; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Class, - 1 => MethodBody, - 2 => MethodDeclaration, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ModuleRef table row - /// - public readonly struct RawModuleRefRow { - public readonly uint Name; - - public RawModuleRefRow(uint Name) => this.Name = Name; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Name, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed TypeSpec table row - /// - public readonly struct RawTypeSpecRow { - public readonly uint Signature; - - public RawTypeSpecRow(uint Signature) => this.Signature = Signature; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Signature, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ImplMap table row - /// - public readonly struct RawImplMapRow { - public readonly ushort MappingFlags; - public readonly uint MemberForwarded; - public readonly uint ImportName; - public readonly uint ImportScope; - - public RawImplMapRow(ushort MappingFlags, uint MemberForwarded, uint ImportName, uint ImportScope) { - this.MappingFlags = MappingFlags; - this.MemberForwarded = MemberForwarded; - this.ImportName = ImportName; - this.ImportScope = ImportScope; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => MappingFlags, - 1 => MemberForwarded, - 2 => ImportName, - 3 => ImportScope, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed FieldRVA table row - /// - public readonly struct RawFieldRVARow { - public readonly uint RVA; - public readonly uint Field; - - public RawFieldRVARow(uint RVA, uint Field) { - this.RVA = RVA; - this.Field = Field; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => RVA, - 1 => Field, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ENCLog table row - /// - public readonly struct RawENCLogRow { - public readonly uint Token; - public readonly uint FuncCode; - - public RawENCLogRow(uint Token, uint FuncCode) { - this.Token = Token; - this.FuncCode = FuncCode; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Token, - 1 => FuncCode, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ENCMap table row - /// - public readonly struct RawENCMapRow { - public readonly uint Token; - - public RawENCMapRow(uint Token) => this.Token = Token; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Token, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Assembly table row - /// - public readonly struct RawAssemblyRow { - public readonly uint HashAlgId; - public readonly ushort MajorVersion; - public readonly ushort MinorVersion; - public readonly ushort BuildNumber; - public readonly ushort RevisionNumber; - public readonly uint Flags; - public readonly uint PublicKey; - public readonly uint Name; - public readonly uint Locale; - - public RawAssemblyRow(uint HashAlgId, ushort MajorVersion, ushort MinorVersion, ushort BuildNumber, ushort RevisionNumber, uint Flags, uint PublicKey, uint Name, uint Locale) { - this.HashAlgId = HashAlgId; - this.MajorVersion = MajorVersion; - this.MinorVersion = MinorVersion; - this.BuildNumber = BuildNumber; - this.RevisionNumber = RevisionNumber; - this.Flags = Flags; - this.PublicKey = PublicKey; - this.Name = Name; - this.Locale = Locale; - } - - /// - /// Gets a column - /// - /// Index of column - /// - 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, - }; - } - - /// - /// Raw contents of an uncompressed AssemblyProcessor table row - /// - public readonly struct RawAssemblyProcessorRow { - public readonly uint Processor; - - public RawAssemblyProcessorRow(uint Processor) => this.Processor = Processor; - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Processor, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed AssemblyOS table row - /// - public readonly struct RawAssemblyOSRow { - public readonly uint OSPlatformId; - public readonly uint OSMajorVersion; - public readonly uint OSMinorVersion; - - public RawAssemblyOSRow(uint OSPlatformId, uint OSMajorVersion, uint OSMinorVersion) { - this.OSPlatformId = OSPlatformId; - this.OSMajorVersion = OSMajorVersion; - this.OSMinorVersion = OSMinorVersion; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => OSPlatformId, - 1 => OSMajorVersion, - 2 => OSMinorVersion, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed AssemblyRef table row - /// - public readonly struct RawAssemblyRefRow { - public readonly ushort MajorVersion; - public readonly ushort MinorVersion; - public readonly ushort BuildNumber; - public readonly ushort RevisionNumber; - public readonly uint Flags; - public readonly uint PublicKeyOrToken; - public readonly uint Name; - public readonly uint Locale; - public readonly uint HashValue; - - public RawAssemblyRefRow(ushort MajorVersion, ushort MinorVersion, ushort BuildNumber, ushort RevisionNumber, uint Flags, uint PublicKeyOrToken, uint Name, uint Locale, uint HashValue) { - this.MajorVersion = MajorVersion; - this.MinorVersion = MinorVersion; - this.BuildNumber = BuildNumber; - this.RevisionNumber = RevisionNumber; - this.Flags = Flags; - this.PublicKeyOrToken = PublicKeyOrToken; - this.Name = Name; - this.Locale = Locale; - this.HashValue = HashValue; - } - - /// - /// Gets a column - /// - /// Index of column - /// - 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, - }; - } - - /// - /// Raw contents of an uncompressed AssemblyRefProcessor table row - /// - public readonly struct RawAssemblyRefProcessorRow { - public readonly uint Processor; - public readonly uint AssemblyRef; - - public RawAssemblyRefProcessorRow(uint Processor, uint AssemblyRef) { - this.Processor = Processor; - this.AssemblyRef = AssemblyRef; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Processor, - 1 => AssemblyRef, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed AssemblyRefOS table row - /// - public readonly struct RawAssemblyRefOSRow { - public readonly uint OSPlatformId; - public readonly uint OSMajorVersion; - public readonly uint OSMinorVersion; - public readonly uint AssemblyRef; - - public RawAssemblyRefOSRow(uint OSPlatformId, uint OSMajorVersion, uint OSMinorVersion, uint AssemblyRef) { - this.OSPlatformId = OSPlatformId; - this.OSMajorVersion = OSMajorVersion; - this.OSMinorVersion = OSMinorVersion; - this.AssemblyRef = AssemblyRef; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => OSPlatformId, - 1 => OSMajorVersion, - 2 => OSMinorVersion, - 3 => AssemblyRef, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed File table row - /// - public readonly struct RawFileRow { - public readonly uint Flags; - public readonly uint Name; - public readonly uint HashValue; - - public RawFileRow(uint Flags, uint Name, uint HashValue) { - this.Flags = Flags; - this.Name = Name; - this.HashValue = HashValue; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Flags, - 1 => Name, - 2 => HashValue, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ExportedType table row - /// - public readonly struct RawExportedTypeRow { - public readonly uint Flags; - public readonly uint TypeDefId; - public readonly uint TypeName; - public readonly uint TypeNamespace; - public readonly uint Implementation; - - public RawExportedTypeRow(uint Flags, uint TypeDefId, uint TypeName, uint TypeNamespace, uint Implementation) { - this.Flags = Flags; - this.TypeDefId = TypeDefId; - this.TypeName = TypeName; - this.TypeNamespace = TypeNamespace; - this.Implementation = Implementation; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Flags, - 1 => TypeDefId, - 2 => TypeName, - 3 => TypeNamespace, - 4 => Implementation, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ManifestResource table row - /// - public readonly struct RawManifestResourceRow { - public readonly uint Offset; - public readonly uint Flags; - public readonly uint Name; - public readonly uint Implementation; - - public RawManifestResourceRow(uint Offset, uint Flags, uint Name, uint Implementation) { - this.Offset = Offset; - this.Flags = Flags; - this.Name = Name; - this.Implementation = Implementation; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Offset, - 1 => Flags, - 2 => Name, - 3 => Implementation, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed NestedClass table row - /// - public readonly struct RawNestedClassRow { - public readonly uint NestedClass; - public readonly uint EnclosingClass; - - public RawNestedClassRow(uint NestedClass, uint EnclosingClass) { - this.NestedClass = NestedClass; - this.EnclosingClass = EnclosingClass; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => NestedClass, - 1 => EnclosingClass, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed GenericParam table row - /// - public readonly struct RawGenericParamRow { - public readonly ushort Number; - public readonly ushort Flags; - public readonly uint Owner; - public readonly uint Name; - public readonly uint Kind; - - public RawGenericParamRow(ushort Number, ushort Flags, uint Owner, uint Name, uint Kind) { - this.Number = Number; - this.Flags = Flags; - this.Owner = Owner; - this.Name = Name; - this.Kind = Kind; - } - - public RawGenericParamRow(ushort Number, ushort Flags, uint Owner, uint Name) { - this.Number = Number; - this.Flags = Flags; - this.Owner = Owner; - this.Name = Name; - Kind = 0; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Number, - 1 => Flags, - 2 => Owner, - 3 => Name, - 4 => Kind, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MethodSpec table row - /// - public readonly struct RawMethodSpecRow { - public readonly uint Method; - public readonly uint Instantiation; - - public RawMethodSpecRow(uint Method, uint Instantiation) { - this.Method = Method; - this.Instantiation = Instantiation; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Method, - 1 => Instantiation, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed GenericParamConstraint table row - /// - public readonly struct RawGenericParamConstraintRow { - public readonly uint Owner; - public readonly uint Constraint; - - public RawGenericParamConstraintRow(uint Owner, uint Constraint) { - this.Owner = Owner; - this.Constraint = Constraint; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Owner, - 1 => Constraint, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed Document table row - /// - public readonly struct RawDocumentRow { - public readonly uint Name; - public readonly uint HashAlgorithm; - public readonly uint Hash; - public readonly uint Language; - - public RawDocumentRow(uint Name, uint HashAlgorithm, uint Hash, uint Language) { - this.Name = Name; - this.HashAlgorithm = HashAlgorithm; - this.Hash = Hash; - this.Language = Language; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Name, - 1 => HashAlgorithm, - 2 => Hash, - 3 => Language, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed MethodDebugInformation table row - /// - public readonly struct RawMethodDebugInformationRow { - public readonly uint Document; - public readonly uint SequencePoints; - - public RawMethodDebugInformationRow(uint Document, uint SequencePoints) { - this.Document = Document; - this.SequencePoints = SequencePoints; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Document, - 1 => SequencePoints, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed LocalScope table row - /// - public readonly struct RawLocalScopeRow { - public readonly uint Method; - public readonly uint ImportScope; - public readonly uint VariableList; - public readonly uint ConstantList; - public readonly uint StartOffset; - public readonly uint Length; - - 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; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Method, - 1 => ImportScope, - 2 => VariableList, - 3 => ConstantList, - 4 => StartOffset, - 5 => Length, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed LocalVariable table row - /// - public readonly struct RawLocalVariableRow { - public readonly ushort Attributes; - public readonly ushort Index; - public readonly uint Name; - - public RawLocalVariableRow(ushort Attributes, ushort Index, uint Name) { - this.Attributes = Attributes; - this.Index = Index; - this.Name = Name; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Attributes, - 1 => Index, - 2 => Name, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed LocalConstant table row - /// - public readonly struct RawLocalConstantRow { - public readonly uint Name; - public readonly uint Signature; - - public RawLocalConstantRow(uint Name, uint Signature) { - this.Name = Name; - this.Signature = Signature; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Name, - 1 => Signature, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed ImportScope table row - /// - public readonly struct RawImportScopeRow { - public readonly uint Parent; - public readonly uint Imports; - - public RawImportScopeRow(uint Parent, uint Imports) { - this.Parent = Parent; - this.Imports = Imports; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => Parent, - 1 => Imports, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed StateMachineMethod table row - /// - public readonly struct RawStateMachineMethodRow { - public readonly uint MoveNextMethod; - public readonly uint KickoffMethod; - - public RawStateMachineMethodRow(uint MoveNextMethod, uint KickoffMethod) { - this.MoveNextMethod = MoveNextMethod; - this.KickoffMethod = KickoffMethod; - } - - /// - /// Gets a column - /// - /// Index of column - /// - public uint this[int index] => - index switch { - 0 => MoveNextMethod, - 1 => KickoffMethod, - _ => 0, - }; - } - - /// - /// Raw contents of an uncompressed CustomDebugInformation table row - /// - public readonly struct RawCustomDebugInformationRow { - public readonly uint Parent; - public readonly uint Kind; - public readonly uint Value; - - public RawCustomDebugInformationRow(uint Parent, uint Kind, uint Value) { - this.Parent = Parent; - this.Kind = Kind; - this.Value = Value; - } - - /// - /// Gets a column - /// - /// Index of column - /// - 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/Plugins/dnlib/DotNet/MD/RidList.cs b/Plugins/dnlib/DotNet/MD/RidList.cs deleted file mode 100644 index 62ed3d5..0000000 --- a/Plugins/dnlib/DotNet/MD/RidList.cs +++ /dev/null @@ -1,141 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - -namespace dnlib.DotNet.MD { - /// - /// Stores a list of rids - /// - [DebuggerDisplay("Count = {Count}")] - public readonly struct RidList : IEnumerable { - readonly uint startRid; - readonly uint length; - readonly IList rids; - - /// - /// Gets the empty instance - /// - public static readonly RidList Empty = Create(0, 0); - - /// - /// Creates a new instance - /// - /// - /// - /// - public static RidList Create(uint startRid, uint length) => new RidList(startRid, length); - - /// - /// Creates a new instance - /// - /// List of valid rids - /// - public static RidList Create(IList rids) => new RidList(rids); - - RidList(uint startRid, uint length) { - this.startRid = startRid; - this.length = length; - rids = null; - } - - RidList(IList rids) { - this.rids = rids ?? throw new ArgumentNullException(nameof(rids)); - startRid = 0; - length = (uint)rids.Count; - } - - /// - /// Gets the 'th rid - /// - /// Index. Must be < - /// A rid or 0 if is invalid - public uint this[int index] { - get { - if (rids is not null) { - if ((uint)index >= (uint)rids.Count) - return 0; - return rids[index]; - } - else { - if ((uint)index >= length) - return 0; - return startRid + (uint)index; - } - } - } - - /// - /// Gets the number of rids it will iterate over - /// - public int Count => (int)length; - - /// - /// Enumerator - /// - public struct Enumerator : IEnumerator { - readonly uint startRid; - readonly uint length; - readonly IList rids; - uint index; - uint current; - - internal Enumerator(in RidList list) { - startRid = list.startRid; - length = list.length; - rids = list.rids; - index = 0; - current = 0; - } - - /// - /// Gets the current rid - /// - public uint Current => current; - object IEnumerator.Current => current; - - /// - /// Disposes this instance - /// - public void Dispose() { } - - /// - /// Moves to the next rid - /// - /// - public bool MoveNext() { - if (rids is null && index < length) { - current = startRid + index; - index++; - return true; - } - return MoveNextOther(); - } - - bool MoveNextOther() { - if (index >= length) { - current = 0; - return false; - } - if (rids is not null) - current = rids[(int)index]; - else - current = startRid + index; - index++; - return true; - } - - void IEnumerator.Reset() => throw new NotSupportedException(); - } - - /// - /// Gets the enumerator - /// - /// - public Enumerator GetEnumerator() => new Enumerator(this); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } -} diff --git a/Plugins/dnlib/DotNet/MD/StorageFlags.cs b/Plugins/dnlib/DotNet/MD/StorageFlags.cs deleted file mode 100644 index c5d0387..0000000 --- a/Plugins/dnlib/DotNet/MD/StorageFlags.cs +++ /dev/null @@ -1,22 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.MD { - /// - /// Storage flags found in the MD header - /// - [Flags] - public enum StorageFlags : byte { - /// - /// Normal flags - /// - Normal = 0, - - /// - /// More data after the header but before the streams. - /// - /// The CLR will fail to load the file if this flag (or any other bits) is set. - ExtraData = 1, - } -} diff --git a/Plugins/dnlib/DotNet/MD/StreamHeader.cs b/Plugins/dnlib/DotNet/MD/StreamHeader.cs deleted file mode 100644 index dac48bf..0000000 --- a/Plugins/dnlib/DotNet/MD/StreamHeader.cs +++ /dev/null @@ -1,85 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Text; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// A metadata stream header - /// - [DebuggerDisplay("O:{offset} L:{streamSize} {name}")] - public sealed class StreamHeader : FileSection { - readonly uint offset; - readonly uint streamSize; - readonly string name; - - /// - /// The offset of the stream relative to the start of the metadata header - /// - public uint Offset => offset; - - /// - /// The size of the stream - /// - public uint StreamSize => streamSize; - - /// - /// The name of the stream - /// - public string Name => name; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public StreamHeader(ref DataReader reader, bool verify) - : this(ref reader, verify, verify, CLRRuntimeReaderKind.CLR, out _) { - } - - 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) - throw new BadImageFormatException("Invalid stream header"); - } - - 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; - for (i = 0; i < maxLen; i++) { - byte b = reader.ReadByte(); - if (b == 0) - break; - sb.Append((char)b); - } - if (verify && i == maxLen) - failedVerification = true; - if (i != maxLen) - reader.Position = origPos + (((uint)i + 1 + 3) & ~3U); - return sb.ToString(); - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/StringsStream.cs b/Plugins/dnlib/DotNet/MD/StringsStream.cs deleted file mode 100644 index e2defdf..0000000 --- a/Plugins/dnlib/DotNet/MD/StringsStream.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Represents the #Strings stream - /// - public sealed class StringsStream : HeapStream { - /// - public StringsStream() { - } - - /// - public StringsStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - } - - /// - /// Reads a - /// - /// Offset of string - /// A instance or null if invalid offset - public UTF8String Read(uint offset) { - if (offset >= StreamLength) - return null; - byte[] data; - var reader = dataReader; - reader.Position = offset; - data = reader.TryReadBytesUntil(0); - if (data is null) - return null; - return new UTF8String(data); - } - - /// - /// Reads a . The empty string is returned if - /// is invalid. - /// - /// Offset of string - /// A instance - public UTF8String ReadNoNull(uint offset) => Read(offset) ?? UTF8String.Empty; - } -} diff --git a/Plugins/dnlib/DotNet/MD/Table.cs b/Plugins/dnlib/DotNet/MD/Table.cs deleted file mode 100644 index 6cf1115..0000000 --- a/Plugins/dnlib/DotNet/MD/Table.cs +++ /dev/null @@ -1,116 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.MD { - /// - /// The metadata tables - /// - public enum Table : byte { - /// Module table (00h) - Module, - /// TypeRef table (01h) - TypeRef, - /// TypeDef table (02h) - TypeDef, - /// FieldPtr table (03h) - FieldPtr, - /// Field table (04h) - Field, - /// MethodPtr table (05h) - MethodPtr, - /// Method table (06h) - Method, - /// ParamPtr table (07h) - ParamPtr, - /// Param table (08h) - Param, - /// InterfaceImpl table (09h) - InterfaceImpl, - /// MemberRef table (0Ah) - MemberRef, - /// Constant table (0Bh) - Constant, - /// CustomAttribute table (0Ch) - CustomAttribute, - /// FieldMarshal table (0Dh) - FieldMarshal, - /// DeclSecurity table (0Eh) - DeclSecurity, - /// ClassLayout table (0Fh) - ClassLayout, - /// FieldLayout table (10h) - FieldLayout, - /// StandAloneSig table (11h) - StandAloneSig, - /// EventMap table (12h) - EventMap, - /// EventPtr table (13h) - EventPtr, - /// Event table (14h) - Event, - /// PropertyMap table (15h) - PropertyMap, - /// PropertyPtr table (16h) - PropertyPtr, - /// Property table (17h) - Property, - /// MethodSemantics table (18h) - MethodSemantics, - /// MethodImpl table (19h) - MethodImpl, - /// ModuleRef table (1Ah) - ModuleRef, - /// TypeSpec table (1Bh) - TypeSpec, - /// ImplMap table (1Ch) - ImplMap, - /// FieldRVA table (1Dh) - FieldRVA, - /// ENCLog table (1Eh) - ENCLog, - /// ENCMap table (1Fh) - ENCMap, - /// Assembly table (20h) - Assembly, - /// AssemblyProcessor table (21h) - AssemblyProcessor, - /// AssemblyOS table (22h) - AssemblyOS, - /// AssemblyRef table (23h) - AssemblyRef, - /// AssemblyRefProcessor table (24h) - AssemblyRefProcessor, - /// AssemblyRefOS table (25h) - AssemblyRefOS, - /// File table (26h) - File, - /// ExportedType table (27h) - ExportedType, - /// ManifestResource table (28h) - ManifestResource, - /// NestedClass table (29h) - NestedClass, - /// GenericParam table (2Ah) - GenericParam, - /// MethodSpec table (2Bh) - 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/Plugins/dnlib/DotNet/MD/TableInfo.cs b/Plugins/dnlib/DotNet/MD/TableInfo.cs deleted file mode 100644 index 1f15b5d..0000000 --- a/Plugins/dnlib/DotNet/MD/TableInfo.cs +++ /dev/null @@ -1,65 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; - -namespace dnlib.DotNet.MD { - /// - /// Info about one MD table - /// - [DebuggerDisplay("{rowSize} {name}")] - public sealed class TableInfo { - readonly Table table; - int rowSize; - readonly ColumnInfo[] columns; - readonly string name; - - /// - /// Returns the table type - /// - public Table Table => table; - - /// - /// Returns the total size of a row in bytes - /// - public int RowSize { - get => rowSize; - internal set => rowSize = value; - } - - /// - /// Returns all the columns - /// - public ColumnInfo[] Columns => columns; - - /// - /// Returns the name of the table - /// - public string Name => name; - - /// - /// Constructor - /// - /// Table type - /// Table name - /// All columns - public TableInfo(Table table, string name, ColumnInfo[] columns) { - this.table = table; - this.name = name; - this.columns = columns; - } - - /// - /// Constructor - /// - /// Table type - /// Table name - /// All columns - /// Row size - public TableInfo(Table table, string name, ColumnInfo[] columns, int rowSize) { - this.table = table; - this.name = name; - this.columns = columns; - this.rowSize = rowSize; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/TablesStream.cs b/Plugins/dnlib/DotNet/MD/TablesStream.cs deleted file mode 100644 index 3e291ef..0000000 --- a/Plugins/dnlib/DotNet/MD/TablesStream.cs +++ /dev/null @@ -1,394 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// .NET metadata tables stream - /// - public sealed partial class TablesStream : DotNetStream { - bool initialized; - uint reserved1; - byte majorVersion; - byte minorVersion; - MDStreamFlags flags; - byte log2Rid; - ulong validMask; - ulong sortedMask; - uint extraData; - MDTable[] mdTables; - uint mdTablesPos; - - IColumnReader columnReader; - IRowReader methodRowReader; - readonly CLRRuntimeReaderKind runtime; - -#pragma warning disable 1591 // XML doc comment - public MDTable ModuleTable { get; private set; } - public MDTable TypeRefTable { get; private set; } - public MDTable TypeDefTable { get; private set; } - public MDTable FieldPtrTable { get; private set; } - public MDTable FieldTable { get; private set; } - public MDTable MethodPtrTable { get; private set; } - public MDTable MethodTable { get; private set; } - public MDTable ParamPtrTable { get; private set; } - public MDTable ParamTable { get; private set; } - public MDTable InterfaceImplTable { get; private set; } - public MDTable MemberRefTable { get; private set; } - public MDTable ConstantTable { get; private set; } - public MDTable CustomAttributeTable { get; private set; } - public MDTable FieldMarshalTable { get; private set; } - public MDTable DeclSecurityTable { get; private set; } - public MDTable ClassLayoutTable { get; private set; } - public MDTable FieldLayoutTable { get; private set; } - public MDTable StandAloneSigTable { get; private set; } - public MDTable EventMapTable { get; private set; } - public MDTable EventPtrTable { get; private set; } - public MDTable EventTable { get; private set; } - public MDTable PropertyMapTable { get; private set; } - public MDTable PropertyPtrTable { get; private set; } - public MDTable PropertyTable { get; private set; } - public MDTable MethodSemanticsTable { get; private set; } - public MDTable MethodImplTable { get; private set; } - public MDTable ModuleRefTable { get; private set; } - public MDTable TypeSpecTable { get; private set; } - public MDTable ImplMapTable { get; private set; } - public MDTable FieldRVATable { get; private set; } - public MDTable ENCLogTable { get; private set; } - public MDTable ENCMapTable { get; private set; } - public MDTable AssemblyTable { get; private set; } - public MDTable AssemblyProcessorTable { get; private set; } - public MDTable AssemblyOSTable { get; private set; } - public MDTable AssemblyRefTable { get; private set; } - public MDTable AssemblyRefProcessorTable { get; private set; } - public MDTable AssemblyRefOSTable { get; private set; } - public MDTable FileTable { get; private set; } - public MDTable ExportedTypeTable { get; private set; } - public MDTable ManifestResourceTable { get; private set; } - public MDTable NestedClassTable { get; private set; } - public MDTable GenericParamTable { get; private set; } - public MDTable MethodSpecTable { get; private set; } - public MDTable GenericParamConstraintTable { 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 - - /// - /// Gets/sets the column reader - /// - public IColumnReader ColumnReader { - get => columnReader; - set => columnReader = value; - } - - /// - /// Gets/sets the Method table reader - /// - public IRowReader MethodRowReader { - get => methodRowReader; - set => methodRowReader = value; - } - - /// - /// Gets the reserved field - /// - 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 => (ushort)((majorVersion << 8) | minorVersion); - - /// - /// Gets - /// - public MDStreamFlags Flags => flags; - - /// - /// Gets the reserved log2 rid field - /// - public byte Log2Rid => log2Rid; - - /// - /// Gets the valid mask - /// - public ulong ValidMask => validMask; - - /// - /// Gets the sorted mask - /// - public ulong SortedMask => sortedMask; - - /// - /// Gets the extra data - /// - public uint ExtraData => extraData; - - /// - /// Gets the MD tables - /// - public MDTable[] MDTables => mdTables; - - /// - /// Gets the bit - /// - public bool HasBigStrings => (flags & MDStreamFlags.BigStrings) != 0; - - /// - /// Gets the bit - /// - public bool HasBigGUID => (flags & MDStreamFlags.BigGUID) != 0; - - /// - /// Gets the bit - /// - public bool HasBigBlob => (flags & MDStreamFlags.BigBlob) != 0; - - /// - /// Gets the bit - /// - public bool HasPadding => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.Padding) != 0; - - /// - /// Gets the bit - /// - public bool HasDeltaOnly => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.DeltaOnly) != 0; - - /// - /// Gets the bit - /// - public bool HasExtraData => runtime == CLRRuntimeReaderKind.CLR && (flags & MDStreamFlags.ExtraData) != 0; - - /// - /// Gets the bit - /// - 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; - } - - /// - /// Initializes MD tables - /// - /// Type system table rows (from #Pdb stream) - 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; - - var reader = dataReader; - reserved1 = reader.ReadUInt32(); - majorVersion = reader.ReadByte(); - minorVersion = reader.ReadByte(); - flags = (MDStreamFlags)reader.ReadByte(); - 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(); - 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]; - - ulong valid = validMask; - 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; - if (i < mdTables.Length) - mdTables[i] = new MDTable((Table)i, rows, tableInfos[i]); - } - - if (HasExtraData) - extraData = reader.ReadUInt32(); - - var debugSizes = sizes; - if (typeSystemTableRows is not 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, forceAllBig); - - mdTablesPos = reader.Position; - InitializeMdTableReaders(); - InitializeTables(); - } - - /// - protected override void OnReaderRecreated() => InitializeMdTableReaders(); - - void InitializeMdTableReaders() { - var reader = dataReader; - reader.Position = mdTablesPos; - 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) - throw new BadImageFormatException("Too big MD table"); - currentPos = newPos; - } - } - - void InitializeTables() { - ModuleTable = mdTables[(int)Table.Module]; - TypeRefTable = mdTables[(int)Table.TypeRef]; - TypeDefTable = mdTables[(int)Table.TypeDef]; - FieldPtrTable = mdTables[(int)Table.FieldPtr]; - FieldTable = mdTables[(int)Table.Field]; - MethodPtrTable = mdTables[(int)Table.MethodPtr]; - MethodTable = mdTables[(int)Table.Method]; - ParamPtrTable = mdTables[(int)Table.ParamPtr]; - ParamTable = mdTables[(int)Table.Param]; - InterfaceImplTable = mdTables[(int)Table.InterfaceImpl]; - MemberRefTable = mdTables[(int)Table.MemberRef]; - ConstantTable = mdTables[(int)Table.Constant]; - CustomAttributeTable = mdTables[(int)Table.CustomAttribute]; - FieldMarshalTable = mdTables[(int)Table.FieldMarshal]; - DeclSecurityTable = mdTables[(int)Table.DeclSecurity]; - ClassLayoutTable = mdTables[(int)Table.ClassLayout]; - FieldLayoutTable = mdTables[(int)Table.FieldLayout]; - StandAloneSigTable = mdTables[(int)Table.StandAloneSig]; - EventMapTable = mdTables[(int)Table.EventMap]; - EventPtrTable = mdTables[(int)Table.EventPtr]; - EventTable = mdTables[(int)Table.Event]; - PropertyMapTable = mdTables[(int)Table.PropertyMap]; - PropertyPtrTable = mdTables[(int)Table.PropertyPtr]; - PropertyTable = mdTables[(int)Table.Property]; - MethodSemanticsTable = mdTables[(int)Table.MethodSemantics]; - MethodImplTable = mdTables[(int)Table.MethodImpl]; - ModuleRefTable = mdTables[(int)Table.ModuleRef]; - TypeSpecTable = mdTables[(int)Table.TypeSpec]; - ImplMapTable = mdTables[(int)Table.ImplMap]; - FieldRVATable = mdTables[(int)Table.FieldRVA]; - ENCLogTable = mdTables[(int)Table.ENCLog]; - ENCMapTable = mdTables[(int)Table.ENCMap]; - AssemblyTable = mdTables[(int)Table.Assembly]; - AssemblyProcessorTable = mdTables[(int)Table.AssemblyProcessor]; - AssemblyOSTable = mdTables[(int)Table.AssemblyOS]; - AssemblyRefTable = mdTables[(int)Table.AssemblyRef]; - AssemblyRefProcessorTable = mdTables[(int)Table.AssemblyRefProcessor]; - AssemblyRefOSTable = mdTables[(int)Table.AssemblyRefOS]; - FileTable = mdTables[(int)Table.File]; - ExportedTypeTable = mdTables[(int)Table.ExportedType]; - ManifestResourceTable = mdTables[(int)Table.ManifestResource]; - NestedClassTable = mdTables[(int)Table.NestedClass]; - GenericParamTable = mdTables[(int)Table.GenericParam]; - MethodSpecTable = mdTables[(int)Table.MethodSpec]; - GenericParamConstraintTable = mdTables[(int)Table.GenericParamConstraint]; - 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]; - } - - /// - protected override void Dispose(bool disposing) { - if (disposing) { - var mt = mdTables; - if (mt is not null) { - foreach (var mdTable in mt) { - if (mdTable is not null) - mdTable.Dispose(); - } - mdTables = null; - } - } - base.Dispose(disposing); - } - - /// - /// Returns a MD table - /// - /// The table type - /// A or null if table doesn't exist - public MDTable Get(Table table) { - int index = (int)table; - if ((uint)index >= (uint)mdTables.Length) - return null; - return mdTables[index]; - } - - /// - /// Checks whether a table exists - /// - /// The table type - /// true if the table exists - public bool HasTable(Table table) => (uint)table < (uint)mdTables.Length; - - /// - /// Checks whether table is sorted - /// - /// The table - public bool IsSorted(MDTable table) { - int index = (int)table.Table; - if ((uint)index >= 64) - return false; - return (sortedMask & (1UL << index)) != 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/TablesStream_Read.cs b/Plugins/dnlib/DotNet/MD/TablesStream_Read.cs deleted file mode 100644 index 6f8dc7a..0000000 --- a/Plugins/dnlib/DotNet/MD/TablesStream_Read.cs +++ /dev/null @@ -1,1171 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; - -namespace dnlib.DotNet.MD { - public partial class TablesStream { - /// - /// Reads a raw Module row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadModuleRow(uint rid, out RawModuleRow row) { - var table = ModuleTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawModuleRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader), - table.Column4.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw TypeRef row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadTypeRefRow(uint rid, out RawTypeRefRow row) { - var table = TypeRefTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawTypeRefRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw TypeDef row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadTypeDefRow(uint rid, out RawTypeDefRow row) { - var table = TypeDefTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawTypeDefRow( - reader.Unsafe_ReadUInt32(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader), - table.Column4.Unsafe_Read24(ref reader), - table.Column5.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw FieldPtr row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFieldPtrRow(uint rid, out RawFieldPtrRow row) { - var table = FieldPtrTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFieldPtrRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Field row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFieldRow(uint rid, out RawFieldRow row) { - var table = FieldTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFieldRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw MethodPtr row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodPtrRow(uint rid, out RawMethodPtrRow row) { - var table = MethodPtrTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodPtrRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Method row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodRow(uint rid, out RawMethodRow row) { - var table = MethodTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var mrr = methodRowReader; - if (mrr is not null && mrr.TryReadRow(rid, out row)) - return true; - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - table.Column3.Unsafe_Read24(ref reader), - table.Column4.Unsafe_Read24(ref reader), - table.Column5.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ParamPtr row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadParamPtrRow(uint rid, out RawParamPtrRow row) { - var table = ParamPtrTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawParamPtrRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Param row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadParamRow(uint rid, out RawParamRow row) { - var table = ParamTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawParamRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw InterfaceImpl row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadInterfaceImplRow(uint rid, out RawInterfaceImplRow row) { - var table = InterfaceImplTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawInterfaceImplRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw MemberRef row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMemberRefRow(uint rid, out RawMemberRefRow row) { - var table = MemberRefTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMemberRefRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Constant row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadConstantRow(uint rid, out RawConstantRow row) { - var table = ConstantTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawConstantRow( - reader.Unsafe_ReadByte(), - reader.Unsafe_ReadByte(), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw CustomAttribute row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadCustomAttributeRow(uint rid, out RawCustomAttributeRow row) { - var table = CustomAttributeTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawCustomAttributeRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw FieldMarshal row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFieldMarshalRow(uint rid, out RawFieldMarshalRow row) { - var table = FieldMarshalTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFieldMarshalRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw DeclSecurity row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadDeclSecurityRow(uint rid, out RawDeclSecurityRow row) { - var table = DeclSecurityTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawDeclSecurityRow( - (short)reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ClassLayout row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadClassLayoutRow(uint rid, out RawClassLayoutRow row) { - var table = ClassLayoutTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawClassLayoutRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt32(), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw FieldLayout row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFieldLayoutRow(uint rid, out RawFieldLayoutRow row) { - var table = FieldLayoutTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFieldLayoutRow( - reader.Unsafe_ReadUInt32(), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw StandAloneSig row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadStandAloneSigRow(uint rid, out RawStandAloneSigRow row) { - var table = StandAloneSigTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawStandAloneSigRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw EventMap row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadEventMapRow(uint rid, out RawEventMapRow row) { - var table = EventMapTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawEventMapRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw EventPtr row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadEventPtrRow(uint rid, out RawEventPtrRow row) { - var table = EventPtrTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawEventPtrRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Event row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadEventRow(uint rid, out RawEventRow row) { - var table = EventTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawEventRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw PropertyMap row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadPropertyMapRow(uint rid, out RawPropertyMapRow row) { - var table = PropertyMapTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawPropertyMapRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw PropertyPtr row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadPropertyPtrRow(uint rid, out RawPropertyPtrRow row) { - var table = PropertyPtrTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawPropertyPtrRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Property row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadPropertyRow(uint rid, out RawPropertyRow row) { - var table = PropertyTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawPropertyRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw MethodSemantics row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodSemanticsRow(uint rid, out RawMethodSemanticsRow row) { - var table = MethodSemanticsTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodSemanticsRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw MethodImpl row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodImplRow(uint rid, out RawMethodImplRow row) { - var table = MethodImplTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodImplRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ModuleRef row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadModuleRefRow(uint rid, out RawModuleRefRow row) { - var table = ModuleRefTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawModuleRefRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw TypeSpec row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadTypeSpecRow(uint rid, out RawTypeSpecRow row) { - var table = TypeSpecTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawTypeSpecRow(table.Column0.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ImplMap row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadImplMapRow(uint rid, out RawImplMapRow row) { - var table = ImplMapTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawImplMapRow( - reader.Unsafe_ReadUInt16(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw FieldRVA row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFieldRVARow(uint rid, out RawFieldRVARow row) { - var table = FieldRVATable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFieldRVARow( - reader.Unsafe_ReadUInt32(), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ENCLog row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadENCLogRow(uint rid, out RawENCLogRow row) { - var table = ENCLogTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawENCLogRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32()); - return true; - } - - /// - /// Reads a raw ENCMap row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadENCMapRow(uint rid, out RawENCMapRow row) { - var table = ENCMapTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawENCMapRow(reader.Unsafe_ReadUInt32()); - return true; - } - - /// - /// Reads a raw Assembly row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyRow(uint rid, out RawAssemblyRow row) { - var table = AssemblyTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt32(), - table.Column6.Unsafe_Read24(ref reader), - table.Column7.Unsafe_Read24(ref reader), - table.Column8.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw AssemblyProcessor row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyProcessorRow(uint rid, out RawAssemblyProcessorRow row) { - var table = AssemblyProcessorTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyProcessorRow(reader.Unsafe_ReadUInt32()); - return true; - } - - /// - /// Reads a raw AssemblyOS row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyOSRow(uint rid, out RawAssemblyOSRow row) { - var table = AssemblyOSTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyOSRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32()); - return true; - } - - /// - /// Reads a raw AssemblyRef row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyRefRow(uint rid, out RawAssemblyRefRow row) { - var table = AssemblyRefTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyRefRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt32(), - table.Column5.Unsafe_Read24(ref reader), - table.Column6.Unsafe_Read24(ref reader), - table.Column7.Unsafe_Read24(ref reader), - table.Column8.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw AssemblyRefProcessor row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyRefProcessorRow(uint rid, out RawAssemblyRefProcessorRow row) { - var table = AssemblyRefProcessorTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyRefProcessorRow( - reader.Unsafe_ReadUInt32(), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw AssemblyRefOS row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadAssemblyRefOSRow(uint rid, out RawAssemblyRefOSRow row) { - var table = AssemblyRefOSTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawAssemblyRefOSRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32(), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw File row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadFileRow(uint rid, out RawFileRow row) { - var table = FileTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawFileRow( - reader.Unsafe_ReadUInt32(), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ExportedType row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadExportedTypeRow(uint rid, out RawExportedTypeRow row) { - var table = ExportedTypeTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawExportedTypeRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32(), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader), - table.Column4.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ManifestResource row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadManifestResourceRow(uint rid, out RawManifestResourceRow row) { - var table = ManifestResourceTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawManifestResourceRow( - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32(), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw NestedClass row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadNestedClassRow(uint rid, out RawNestedClassRow row) { - var table = NestedClassTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawNestedClassRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw GenericParam row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadGenericParamRow(uint rid, out RawGenericParamRow row) { - var table = GenericParamTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - if (table.Column4 is null) { - row = new RawGenericParamRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - else { - row = new RawGenericParamRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader), - table.Column4.Unsafe_Read24(ref reader)); - return true; - } - } - - /// - /// Reads a raw MethodSpec row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodSpecRow(uint rid, out RawMethodSpecRow row) { - var table = MethodSpecTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodSpecRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw GenericParamConstraint row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadGenericParamConstraintRow(uint rid, out RawGenericParamConstraintRow row) { - var table = GenericParamConstraintTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawGenericParamConstraintRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw Document row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadDocumentRow(uint rid, out RawDocumentRow row) { - var table = DocumentTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawDocumentRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw MethodDebugInformation row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadMethodDebugInformationRow(uint rid, out RawMethodDebugInformationRow row) { - var table = MethodDebugInformationTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawMethodDebugInformationRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw LocalScope row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadLocalScopeRow(uint rid, out RawLocalScopeRow row) { - var table = LocalScopeTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawLocalScopeRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader), - table.Column3.Unsafe_Read24(ref reader), - reader.Unsafe_ReadUInt32(), - reader.Unsafe_ReadUInt32()); - return true; - } - - /// - /// Reads a raw LocalVariable row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadLocalVariableRow(uint rid, out RawLocalVariableRow row) { - var table = LocalVariableTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawLocalVariableRow( - reader.Unsafe_ReadUInt16(), - reader.Unsafe_ReadUInt16(), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw LocalConstant row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadLocalConstantRow(uint rid, out RawLocalConstantRow row) { - var table = LocalConstantTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawLocalConstantRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw ImportScope row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadImportScopeRow(uint rid, out RawImportScopeRow row) { - var table = ImportScopeTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawImportScopeRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw StateMachineMethod row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadStateMachineMethodRow(uint rid, out RawStateMachineMethodRow row) { - var table = StateMachineMethodTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawStateMachineMethodRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a raw CustomDebugInformation row or returns false if the row doesn't exist - /// - /// Row ID - /// Row data - /// - public bool TryReadCustomDebugInformationRow(uint rid, out RawCustomDebugInformationRow row) { - var table = CustomDebugInformationTable; - if (table.IsInvalidRID(rid)) { - row = default; - return false; - } - var reader = table.DataReader; - reader.Position = (rid - 1) * (uint)table.TableInfo.RowSize; - row = new RawCustomDebugInformationRow( - table.Column0.Unsafe_Read24(ref reader), - table.Column1.Unsafe_Read24(ref reader), - table.Column2.Unsafe_Read24(ref reader)); - return true; - } - - /// - /// Reads a column - /// - /// The table - /// Row ID - /// Column index in - /// Result is put here or 0 if we return false - /// true if we could read the column, false otherwise - public bool TryReadColumn(MDTable table, uint rid, int colIndex, out uint value) => - TryReadColumn(table, rid, table.TableInfo.Columns[colIndex], out value); - - /// - /// Reads a column - /// - /// The table - /// Row ID - /// Column - /// Result is put here or 0 if we return false - /// true if we could read the column, false otherwise - public bool TryReadColumn(MDTable table, uint rid, ColumnInfo column, out uint value) { - if (table.IsInvalidRID(rid)) { - value = 0; - return false; - } - var cr = columnReader; - 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; - value = column.Read(ref reader); - return true; - } - - internal bool TryReadColumn24(MDTable table, uint rid, int colIndex, out uint value) => - TryReadColumn24(table, rid, table.TableInfo.Columns[colIndex], out value); - - internal bool TryReadColumn24(MDTable table, uint rid, ColumnInfo column, out uint value) { - Debug.Assert(column.Size == 2 || column.Size == 4); - if (table.IsInvalidRID(rid)) { - value = 0; - return false; - } - var cr = columnReader; - 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; - value = column.Size == 2 ? reader.Unsafe_ReadUInt16() : reader.Unsafe_ReadUInt32(); - return true; - } - } -} diff --git a/Plugins/dnlib/DotNet/MD/USStream.cs b/Plugins/dnlib/DotNet/MD/USStream.cs deleted file mode 100644 index a6be17e..0000000 --- a/Plugins/dnlib/DotNet/MD/USStream.cs +++ /dev/null @@ -1,57 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.DotNet.MD { - /// - /// Represents the #US stream - /// - public sealed class USStream : HeapStream { - /// - public USStream() { - } - - /// - public USStream(DataReaderFactory mdReaderFactory, uint metadataBaseOffset, StreamHeader streamHeader) - : base(mdReaderFactory, metadataBaseOffset, streamHeader) { - } - - /// - /// Reads a unicode string - /// - /// Offset of unicode string - /// A string or null if is invalid - public string Read(uint offset) { - if (offset == 0) - return string.Empty; - if (!IsValidOffset(offset)) - return null; - var reader = dataReader; - reader.Position = offset; - if (!reader.TryReadCompressedUInt32(out uint length)) - return null; - if (!reader.CanRead(length)) - return null; - try { - return reader.ReadUtf16String((int)(length / 2)); - } - catch (OutOfMemoryException) { - throw; - } - catch { - // It's possible that an exception is thrown when converting a char* to - // a string. If so, return an empty string. - return string.Empty; - } - } - - /// - /// Reads data just like , but returns an empty string if - /// offset is invalid - /// - /// Offset of unicode string - /// The string - public string ReadNoNull(uint offset) => Read(offset) ?? string.Empty; - } -} diff --git a/Plugins/dnlib/DotNet/MDToken.cs b/Plugins/dnlib/DotNet/MDToken.cs deleted file mode 100644 index 3663039..0000000 --- a/Plugins/dnlib/DotNet/MDToken.cs +++ /dev/null @@ -1,157 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet { - /// - /// Metadata token - /// - [DebuggerDisplay("{Table} {Rid}")] - public readonly struct MDToken : IEquatable, IComparable { - /// - /// Mask to get the rid from a raw metadata token - /// - public const uint RID_MASK = 0x00FFFFFF; - - /// - /// Max rid value - /// - public const uint RID_MAX = RID_MASK; - - /// - /// Number of bits to right shift a raw metadata token to get the table index - /// - public const int TABLE_SHIFT = 24; - - readonly uint token; - - /// - /// Returns the table type - /// - public Table Table => ToTable(token); - - /// - /// Returns the row id - /// - public uint Rid => ToRID(token); - - /// - /// Returns the raw token - /// - public uint Raw => token; - - /// - /// Returns true if it's a null token - /// - public bool IsNull => Rid == 0; - - /// - /// Constructor - /// - /// Raw token - public MDToken(uint token) => this.token = token; - - /// - /// Constructor - /// - /// Raw token - public MDToken(int token) - : this((uint)token) { - } - - /// - /// Constructor - /// - /// The table type - /// Row id - public MDToken(Table table, uint rid) - : this(((uint)table << TABLE_SHIFT) | rid) { - } - - /// - /// Constructor - /// - /// The table type - /// Row id - public MDToken(Table table, int rid) - : this(((uint)table << TABLE_SHIFT) | (uint)rid) { - } - - /// - /// Returns the rid (row ID) - /// - /// A raw metadata token - /// A rid - 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) => ToRID((uint)token); - - /// - /// Returns the table - /// - /// A raw metadata token - /// A metadata table index - 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) => ToTable((uint)token); - - /// - /// Gets the token as a raw 32-bit signed integer - /// - public int ToInt32() => (int)token; - - /// - /// Gets the token as a raw 32-bit unsigned integer - /// - public uint ToUInt32() => token; - - /// Overloaded operator - public static bool operator ==(MDToken left, MDToken right) => left.CompareTo(right) == 0; - - /// Overloaded operator - public static bool operator !=(MDToken left, MDToken right) => left.CompareTo(right) != 0; - - /// Overloaded operator - public static bool operator <(MDToken left, MDToken right) => left.CompareTo(right) < 0; - - /// Overloaded operator - public static bool operator >(MDToken left, MDToken right) => left.CompareTo(right) > 0; - - /// Overloaded operator - public static bool operator <=(MDToken left, MDToken right) => left.CompareTo(right) <= 0; - - /// Overloaded operator - public static bool operator >=(MDToken left, MDToken right) => left.CompareTo(right) >= 0; - - /// - public int CompareTo(MDToken other) => token.CompareTo(other.token); - - /// - public bool Equals(MDToken other) => CompareTo(other) == 0; - - /// - public override bool Equals(object obj) { - if (!(obj is MDToken)) - return false; - return Equals((MDToken)obj); - } - - /// - public override int GetHashCode() => (int)token; - - /// - public override string ToString() => token.ToString("X8"); - } -} diff --git a/Plugins/dnlib/DotNet/ManifestResource.cs b/Plugins/dnlib/DotNet/ManifestResource.cs deleted file mode 100644 index c907349..0000000 --- a/Plugins/dnlib/DotNet/ManifestResource.cs +++ /dev/null @@ -1,237 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the ManifestResource table - /// - [DebuggerDisplay("{Offset} {Name.String} {Implementation}")] - public abstract class ManifestResource : IHasCustomAttribute, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.ManifestResource, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 18; - - /// - /// From column ManifestResource.Offset - /// - public uint Offset { - get => offset; - set => offset = value; - } - /// - protected uint offset; - - /// - /// From column ManifestResource.Flags - /// - public ManifestResourceAttributes Flags { - get => (ManifestResourceAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column ManifestResource.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column ManifestResource.Implementation - /// - public IImplementation Implementation { - get => implementation; - set => implementation = value; - } - /// - protected IImplementation implementation; - - /// - /// 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; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(ManifestResourceAttributes andMask, ManifestResourceAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Gets/sets the visibility - /// - public ManifestResourceAttributes Visibility { - get => (ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask; - set => ModifyAttributes(~ManifestResourceAttributes.VisibilityMask, value & ManifestResourceAttributes.VisibilityMask); - } - - /// - /// true if is set - /// - public bool IsPublic => ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; - - /// - /// true if is set - /// - public bool IsPrivate => ((ManifestResourceAttributes)attributes & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Private; - } - - /// - /// A ManifestResource row created by the user and not present in the original .NET file - /// - public class ManifestResourceUser : ManifestResource { - /// - /// Default constructor - /// - public ManifestResourceUser() { - } - - /// - /// Constructor - /// - /// Name - /// Implementation - public ManifestResourceUser(UTF8String name, IImplementation implementation) - : this(name, implementation, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Implementation - /// Flags - public ManifestResourceUser(UTF8String name, IImplementation implementation, ManifestResourceAttributes flags) - : this(name, implementation, flags, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Implementation - /// Flags - /// Offset - public ManifestResourceUser(UTF8String name, IImplementation implementation, ManifestResourceAttributes flags, uint offset) { - this.name = name; - this.implementation = implementation; - attributes = (int)flags; - this.offset = offset; - } - } - - /// - /// Created from a row in the ManifestResource table - /// - sealed class ManifestResourceMD : ManifestResource, 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); - } - - /// - /// Constructor - /// - /// The module which contains this ManifestResource row - /// Row ID - /// If is null - /// If is invalid - public ManifestResourceMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ManifestResourceTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"ManifestResource rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadManifestResourceRow(origRid, out var row); - Debug.Assert(b); - offset = row.Offset; - attributes = (int)row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - implementation = readerModule.ResolveImplementation(row.Implementation); - } - } -} diff --git a/Plugins/dnlib/DotNet/ManifestResourceAttributes.cs b/Plugins/dnlib/DotNet/ManifestResourceAttributes.cs deleted file mode 100644 index 100d64e..0000000 --- a/Plugins/dnlib/DotNet/ManifestResourceAttributes.cs +++ /dev/null @@ -1,18 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// ManifestResource flags. See CorHdr.h/CorManifestResourceFlags - /// - [Flags] - public enum ManifestResourceAttributes : uint { - /// - VisibilityMask = 0x0007, - /// The Resource is exported from the Assembly. - Public = 0x0001, - /// The Resource is private to the Assembly. - Private = 0x0002, - } -} diff --git a/Plugins/dnlib/DotNet/MarshalBlobReader.cs b/Plugins/dnlib/DotNet/MarshalBlobReader.cs deleted file mode 100644 index 0a8b7b3..0000000 --- a/Plugins/dnlib/DotNet/MarshalBlobReader.cs +++ /dev/null @@ -1,141 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; - -namespace dnlib.DotNet { - /// - /// Reads s - /// - public struct MarshalBlobReader { - readonly ModuleDef module; - DataReader reader; - readonly GenericParamContext gpContext; - - /// - /// Reads a from the #Blob heap - /// - /// Module - /// Blob offset - /// A new instance - public static MarshalType Read(ModuleDefMD module, uint sig) => Read(module, module.BlobStream.CreateReader(sig), new GenericParamContext()); - - /// - /// Reads a from the #Blob heap - /// - /// Module - /// Blob offset - /// Generic parameter context - /// A new instance - public static MarshalType Read(ModuleDefMD module, uint sig, GenericParamContext gpContext) => Read(module, module.BlobStream.CreateReader(sig), gpContext); - - /// - /// Reads a from - /// - /// Owner module - /// Marshal data - /// A new instance - public static MarshalType Read(ModuleDef module, byte[] data) => Read(module, ByteArrayDataReaderFactory.CreateReader(data), new GenericParamContext()); - - /// - /// Reads a from - /// - /// Owner module - /// Marshal data - /// Generic parameter context - /// A new instance - public static MarshalType Read(ModuleDef module, byte[] data, GenericParamContext gpContext) => Read(module, ByteArrayDataReaderFactory.CreateReader(data), gpContext); - - /// - /// Reads a from - /// - /// Owner module - /// A reader that will be owned by us - /// A new instance - public static MarshalType Read(ModuleDef module, DataReader reader) => Read(module, reader, new GenericParamContext()); - - /// - /// Reads a from - /// - /// Owner module - /// A reader that will be owned by us - /// Generic parameter context - /// A new instance - public static MarshalType Read(ModuleDef module, DataReader reader, GenericParamContext gpContext) { - var marshalReader = new MarshalBlobReader(module, ref reader, gpContext); - return marshalReader.Read(); - } - - MarshalBlobReader(ModuleDef module, ref DataReader reader, GenericParamContext gpContext) { - this.module = module; - this.reader = reader; - this.gpContext = gpContext; - } - - MarshalType Read() { - MarshalType returnValue; - try { - var nativeType = (NativeType)reader.ReadByte(); - NativeType nt; - int size; - switch (nativeType) { - case NativeType.FixedSysString: - size = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - returnValue = new FixedSysStringMarshalType(size); - break; - - case NativeType.SafeArray: - var vt = CanRead() ? (VariantType)reader.ReadCompressedUInt32() : VariantType.NotInitialized; - var udtName = CanRead() ? ReadUTF8String() : null; - var udtRef = udtName is null ? null : TypeNameParser.ParseReflection(module, UTF8String.ToSystemStringOrEmpty(udtName), null, gpContext); - returnValue = new SafeArrayMarshalType(vt, udtRef); - break; - - case NativeType.FixedArray: - size = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - nt = CanRead() ? (NativeType)reader.ReadCompressedUInt32() : NativeType.NotInitialized; - returnValue = new FixedArrayMarshalType(size, nt); - break; - - case NativeType.Array: - nt = CanRead() ? (NativeType)reader.ReadCompressedUInt32() : NativeType.NotInitialized; - int paramNum = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - size = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - int flags = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - returnValue = new ArrayMarshalType(nt, paramNum, size, flags); - break; - - case NativeType.CustomMarshaler: - var guid = ReadUTF8String(); - var nativeTypeName = ReadUTF8String(); - var custMarshalerName = ReadUTF8String(); - 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; - - case NativeType.IUnknown: - case NativeType.IDispatch: - case NativeType.IntF: - int iidParamIndex = CanRead() ? (int)reader.ReadCompressedUInt32() : -1; - return new InterfaceMarshalType(nativeType, iidParamIndex); - - default: - returnValue = new MarshalType(nativeType); - break; - } - } - catch { - returnValue = new RawMarshalType(reader.ToArray()); - } - - return returnValue; - } - - bool CanRead() => reader.Position < reader.Length; - - UTF8String ReadUTF8String() { - uint len = reader.ReadCompressedUInt32(); - return len == 0 ? UTF8String.Empty : new UTF8String(reader.ReadBytes((int)len)); - } - } -} diff --git a/Plugins/dnlib/DotNet/MarshalType.cs b/Plugins/dnlib/DotNet/MarshalType.cs deleted file mode 100644 index 432e51e..0000000 --- a/Plugins/dnlib/DotNet/MarshalType.cs +++ /dev/null @@ -1,499 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Base class of all marshal types - /// - public class MarshalType { - /// - /// The native type - /// - protected readonly NativeType nativeType; - - /// - /// Gets the - /// - public NativeType NativeType => nativeType; - - /// - /// Constructor - /// - /// Native type - public MarshalType(NativeType nativeType) => this.nativeType = nativeType; - - /// - public override string ToString() => nativeType.ToString(); - } - - /// - /// Contains the raw marshal blob data - /// - public sealed class RawMarshalType : MarshalType { - byte[] data; - - /// - /// Gets/sets the raw data - /// - public byte[] Data { - get => data; - set => data = value; - } - - /// - /// Constructor - /// - /// Raw data - public RawMarshalType(byte[] data) - : base(NativeType.RawBlob) => this.data = data; - } - - /// - /// A marshal type - /// - public sealed class FixedSysStringMarshalType : MarshalType { - int size; - - /// - /// Gets/sets the size - /// - public int Size { - get => size; - set => size = value; - } - - /// - /// true if is valid - /// - public bool IsSizeValid => size >= 0; - - /// - /// Default constructor - /// - public FixedSysStringMarshalType() - : this(-1) { - } - - /// - /// Constructor - /// - /// Size - public FixedSysStringMarshalType(int size) - : base(NativeType.FixedSysString) => this.size = size; - - /// - public override string ToString() { - if (IsSizeValid) - return $"{nativeType} ({size})"; - return $"{nativeType} ()"; - } - } - - /// - /// A marshal type - /// - public sealed class SafeArrayMarshalType : MarshalType { - VariantType vt; - ITypeDefOrRef userDefinedSubType; - - /// - /// Gets/sets the variant type - /// - public VariantType VariantType { - get => vt; - set => vt = value; - } - - /// - /// Gets/sets the user-defined sub type (it's usually null) - /// - public ITypeDefOrRef UserDefinedSubType { - get => userDefinedSubType; - set => userDefinedSubType = value; - } - - /// - /// true if is valid - /// - public bool IsVariantTypeValid => vt != VariantType.NotInitialized; - - /// - /// true if is valid - /// - public bool IsUserDefinedSubTypeValid => userDefinedSubType is not null; - - /// - /// Default constructor - /// - public SafeArrayMarshalType() - : this(VariantType.NotInitialized, null) { - } - - /// - /// Constructor - /// - /// Variant type - public SafeArrayMarshalType(VariantType vt) - : this(vt, null) { - } - - /// - /// Constructor - /// - /// User-defined sub type - public SafeArrayMarshalType(ITypeDefOrRef userDefinedSubType) - : this(VariantType.NotInitialized, userDefinedSubType) { - } - - /// - /// Constructor - /// - /// Variant type - /// User-defined sub type - public SafeArrayMarshalType(VariantType vt, ITypeDefOrRef userDefinedSubType) - : base(NativeType.SafeArray) { - this.vt = vt; - this.userDefinedSubType = userDefinedSubType; - } - - /// - public override string ToString() { - var udt = userDefinedSubType; - if (udt is not null) - return $"{nativeType} ({vt}, {udt})"; - return $"{nativeType} ({vt})"; - } - } - - /// - /// A marshal type - /// - public sealed class FixedArrayMarshalType : MarshalType { - int size; - NativeType elementType; - - /// - /// Gets/sets the element type - /// - public NativeType ElementType { - get => elementType; - set => elementType = value; - } - - /// - /// Gets/sets the size - /// - public int Size { - get => size; - set => size = value; - } - - /// - /// true if is valid - /// - public bool IsElementTypeValid => elementType != NativeType.NotInitialized; - - /// - /// true if is valid - /// - public bool IsSizeValid => size >= 0; - - /// - /// Default constructor - /// - public FixedArrayMarshalType() - : this(0) { - } - - /// - /// Constructor - /// - /// Size - public FixedArrayMarshalType(int size) - : this(size, NativeType.NotInitialized) { - } - - /// - /// Constructor - /// - /// Size - /// Element type - public FixedArrayMarshalType(int size, NativeType elementType) - : base(NativeType.FixedArray) { - this.size = size; - this.elementType = elementType; - } - - /// - public override string ToString() => $"{nativeType} ({size}, {elementType})"; - } - - /// - /// A marshal type - /// - public sealed class ArrayMarshalType : MarshalType { - NativeType elementType; - int paramNum; - int numElems; - int flags; - - /// - /// Gets/sets the element type - /// - public NativeType ElementType { - get => elementType; - set => elementType = value; - } - - /// - /// Gets/sets the parameter number - /// - public int ParamNumber { - get => paramNum; - set => paramNum = value; - } - - /// - /// Gets/sets the size of the array - /// - public int Size { - get => numElems; - set => numElems = value; - } - - /// - /// Gets/sets the flags - /// - public int Flags { - get => flags; - set => flags = value; - } - - /// - /// true if is valid - /// - public bool IsElementTypeValid => elementType != NativeType.NotInitialized; - - /// - /// true if is valid - /// - public bool IsParamNumberValid => paramNum >= 0; - - /// - /// true if is valid - /// - public bool IsSizeValid => numElems >= 0; - - /// - /// true if is valid - /// - public bool IsFlagsValid => flags >= 0; - - const int ntaSizeParamIndexSpecified = 1; - - /// - /// true if ntaSizeParamIndexSpecified bit is set, false if it's not - /// set or if is invalid. - /// - 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 => IsFlagsValid && (flags & ntaSizeParamIndexSpecified) == 0; - - /// - /// Default constructor - /// - public ArrayMarshalType() - : this(NativeType.NotInitialized, -1, -1, -1) { - } - - /// - /// Constructor - /// - /// Element type - public ArrayMarshalType(NativeType elementType) - : this(elementType, -1, -1, -1) { - } - - /// - /// Constructor - /// - /// Element type - /// Parameter number - public ArrayMarshalType(NativeType elementType, int paramNum) - : this(elementType, paramNum, -1, -1) { - } - - /// - /// Constructor - /// - /// Element type - /// Parameter number - /// Number of elements - public ArrayMarshalType(NativeType elementType, int paramNum, int numElems) - : this(elementType, paramNum, numElems, -1) { - } - - /// - /// Constructor - /// - /// Element type - /// Parameter number - /// Number of elements - /// Flags - public ArrayMarshalType(NativeType elementType, int paramNum, int numElems, int flags) - : base(NativeType.Array) { - this.elementType = elementType; - this.paramNum = paramNum; - this.numElems = numElems; - this.flags = flags; - } - - /// - public override string ToString() => $"{nativeType} ({elementType}, {paramNum}, {numElems}, {flags})"; - } - - /// - /// A marshal type - /// - public sealed class CustomMarshalType : MarshalType { - UTF8String guid; - UTF8String nativeTypeName; - ITypeDefOrRef custMarshaler; - UTF8String cookie; - - /// - /// Gets/sets the GUID string - /// - public UTF8String Guid { - get => guid; - set => guid = value; - } - - /// - /// Gets/sets the native type name string - /// - public UTF8String NativeTypeName { - get => nativeTypeName; - set => nativeTypeName = value; - } - - /// - /// Gets/sets the custom marshaler - /// - public ITypeDefOrRef CustomMarshaler { - get => custMarshaler; - set => custMarshaler = value; - } - - /// - /// Gets/sets the cookie string - /// - public UTF8String Cookie { - get => cookie; - set => cookie = value; - } - - /// - /// Default constructor - /// - public CustomMarshalType() - : this(null, null, null, null) { - } - - /// - /// Constructor - /// - /// GUID string - public CustomMarshalType(UTF8String guid) - : this(guid, null, null, null) { - } - - /// - /// Constructor - /// - /// GUID string - /// Native type name string - public CustomMarshalType(UTF8String guid, UTF8String nativeTypeName) - : this(guid, nativeTypeName, null, null) { - } - - /// - /// Constructor - /// - /// GUID string - /// Native type name string - /// Custom marshaler name string - public CustomMarshalType(UTF8String guid, UTF8String nativeTypeName, ITypeDefOrRef custMarshaler) - : this(guid, nativeTypeName, custMarshaler, null) { - } - - /// - /// Constructor - /// - /// GUID string - /// Native type name string - /// Custom marshaler name string - /// Cookie string - public CustomMarshalType(UTF8String guid, UTF8String nativeTypeName, ITypeDefOrRef custMarshaler, UTF8String cookie) - : base(NativeType.CustomMarshaler) { - this.guid = guid; - this.nativeTypeName = nativeTypeName; - this.custMarshaler = custMarshaler; - this.cookie = cookie; - } - - /// - public override string ToString() => $"{nativeType} ({guid}, {nativeTypeName}, {custMarshaler}, {cookie})"; - } - - /// - /// A , or a - /// marshal type - /// - public sealed class InterfaceMarshalType : MarshalType { - int iidParamIndex; - - /// - /// Gets/sets the IID parameter index - /// - public int IidParamIndex { - get => iidParamIndex; - set => iidParamIndex = value; - } - - /// - /// true if is valid - /// - public bool IsIidParamIndexValid => iidParamIndex >= 0; - - /// - /// Constructor - /// - /// Native type - public InterfaceMarshalType(NativeType nativeType) - : this(nativeType, -1) { - } - - /// - /// Constructor - /// - /// Native type - /// IID parameter index - public InterfaceMarshalType(NativeType nativeType, int iidParamIndex) - : base(nativeType) { - if (nativeType != NativeType.IUnknown && - nativeType != NativeType.IDispatch && - nativeType != NativeType.IntF) - throw new ArgumentException("Invalid nativeType"); - this.iidParamIndex = iidParamIndex; - } - - /// - public override string ToString() => $"{nativeType} ({iidParamIndex})"; - } -} diff --git a/Plugins/dnlib/DotNet/MemberFinder.cs b/Plugins/dnlib/DotNet/MemberFinder.cs deleted file mode 100644 index 926f7f3..0000000 --- a/Plugins/dnlib/DotNet/MemberFinder.cs +++ /dev/null @@ -1,766 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet { - /// - /// Finds types, fields, methods, etc in a module. If nothing has been added to the module, it's - /// faster to call ResolveMethodDef(), ResolveTypeRef() etc. - /// - public class MemberFinder { - enum ObjectType { - Unknown, - EventDef, - FieldDef, - GenericParam, - MemberRef, - MethodDef, - MethodSpec, - PropertyDef, - TypeDef, - TypeRef, - TypeSig, - TypeSpec, - ExportedType, - } - - /// - /// All found s - /// - public readonly Dictionary CustomAttributes = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary EventDefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary FieldDefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary GenericParams = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary MemberRefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary MethodDefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary MethodSpecs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary PropertyDefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary TypeDefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary TypeRefs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary TypeSigs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary TypeSpecs = new Dictionary(); - - /// - /// All found s - /// - public readonly Dictionary ExportedTypes = new Dictionary(); - - Stack objectStack; - ModuleDef validModule; - - /// - /// Finds all types, fields, etc - /// - /// The module to scan - /// Itself - public MemberFinder FindAll(ModuleDef module) { - validModule = module; - - // This needs to be big. About 2048 entries should be enough for most though... - objectStack = new Stack(0x1000); - - Add(module); - ProcessAll(); - - objectStack = null; - - return this; - } - - void Push(object mr) { - if (mr is null) - return; - objectStack.Push(mr); - } - - void ProcessAll() { - while (objectStack.Count > 0) { - var o = objectStack.Pop(); - switch (GetObjectType(o)) { - case ObjectType.Unknown: break; - case ObjectType.EventDef: Add((EventDef)o); break; - case ObjectType.FieldDef: Add((FieldDef)o); break; - case ObjectType.GenericParam: Add((GenericParam)o); break; - case ObjectType.MemberRef: Add((MemberRef)o); break; - case ObjectType.MethodDef: Add((MethodDef)o); break; - case ObjectType.MethodSpec: Add((MethodSpec)o); break; - case ObjectType.PropertyDef: Add((PropertyDef)o); break; - case ObjectType.TypeDef: Add((TypeDef)o); break; - case ObjectType.TypeRef: Add((TypeRef)o); break; - 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($"Unknown type: {o.GetType()}"); - } - } - } - - readonly Dictionary toObjectType = new Dictionary(); - ObjectType GetObjectType(object o) { - if (o is null) - return ObjectType.Unknown; - var type = o.GetType(); - if (toObjectType.TryGetValue(type, out var mrType)) - return mrType; - mrType = GetObjectType2(o); - toObjectType[type] = mrType; - return mrType; - } - - static ObjectType GetObjectType2(object o) { - if (o is EventDef) return ObjectType.EventDef; - if (o is FieldDef) return ObjectType.FieldDef; - if (o is GenericParam) return ObjectType.GenericParam; - if (o is MemberRef) return ObjectType.MemberRef; - if (o is MethodDef) return ObjectType.MethodDef; - if (o is MethodSpec) return ObjectType.MethodSpec; - if (o is PropertyDef) return ObjectType.PropertyDef; - if (o is TypeDef) return ObjectType.TypeDef; - if (o is TypeRef) return ObjectType.TypeRef; - if (o is TypeSig) return ObjectType.TypeSig; - if (o is TypeSpec) return ObjectType.TypeSpec; - if (o is ExportedType) return ObjectType.ExportedType; - return ObjectType.Unknown; - } - - void Add(ModuleDef mod) { - Push(mod.ManagedEntryPoint); - Add(mod.CustomAttributes); - Add(mod.Types); - Add(mod.ExportedTypes); - if (mod.IsManifestModule) - Add(mod.Assembly); - Add(mod.VTableFixups); - Add(mod.Resources); - } - - void Add(VTableFixups fixups) { - if (fixups is null) - return; - foreach (var fixup in fixups) { - foreach (var method in fixup) - Push(method); - } - } - - void Add(ResourceCollection resources) { - foreach (var resource in resources) { - Add(resource.CustomAttributes); - } - } - - void Add(AssemblyDef asm) { - if (asm is null) - return; - Add(asm.DeclSecurities); - Add(asm.CustomAttributes); - } - - void Add(CallingConventionSig sig) { - if (sig is null) - return; - - if (sig is FieldSig fs) { - Add(fs); - return; - } - - if (sig is MethodBaseSig mbs) { - Add(mbs); - return; - } - - if (sig is LocalSig ls) { - Add(ls); - return; - } - - if (sig is GenericInstMethodSig gims) { - Add(gims); - return; - } - } - - void Add(FieldSig sig) { - if (sig is null) - return; - Add(sig.Type); - } - - void Add(MethodBaseSig sig) { - if (sig is null) - return; - Add(sig.RetType); - Add(sig.Params); - Add(sig.ParamsAfterSentinel); - } - - void Add(LocalSig sig) { - if (sig is null) - return; - Add(sig.Locals); - } - - void Add(GenericInstMethodSig sig) { - if (sig is null) - return; - Add(sig.GenericArguments); - } - - void Add(IEnumerable cas) { - if (cas is null) - return; - foreach (var ca in cas) - Add(ca); - } - - void Add(CustomAttribute ca) { - if (ca is null || CustomAttributes.ContainsKey(ca)) - return; - CustomAttributes[ca] = true; - Push(ca.Constructor); - Add(ca.ConstructorArguments); - Add(ca.NamedArguments); - } - - void Add(IEnumerable args) { - if (args is null) - return; - foreach (var arg in args) - Add(arg); - } - - 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); - else if(arg.Value is CAArgument boxedArgument) - Add(boxedArgument); - } - - void Add(IEnumerable args) { - if (args is null) - return; - foreach (var arg in args) - Add(arg); - } - - void Add(CANamedArgument arg) { - if (arg is null) - return; - Add(arg.Type); - Add(arg.Argument); - } - - void Add(IEnumerable decls) { - if (decls is null) - return; - foreach (var decl in decls) - Add(decl); - } - - void Add(DeclSecurity decl) { - if (decl is null) - return; - Add(decl.SecurityAttributes); - Add(decl.CustomAttributes); - } - - void Add(IEnumerable secAttrs) { - if (secAttrs is null) - return; - foreach (var secAttr in secAttrs) - Add(secAttr); - } - - void Add(SecurityAttribute secAttr) { - if (secAttr is null) - return; - Add(secAttr.AttributeType); - Add(secAttr.NamedArguments); - } - - void Add(ITypeDefOrRef tdr) { - if (tdr is TypeDef td) { - Add(td); - return; - } - - if (tdr is TypeRef tr) { - Add(tr); - return; - } - - if (tdr is TypeSpec ts) { - Add(ts); - return; - } - } - - void Add(IEnumerable eds) { - if (eds is null) - return; - foreach (var ed in eds) - Add(ed); - } - - void Add(EventDef ed) { - if (ed is null || EventDefs.ContainsKey(ed)) - return; - if (ed.DeclaringType is not null && ed.DeclaringType.Module != validModule) - return; - EventDefs[ed] = true; - Push(ed.EventType); - Add(ed.CustomAttributes); - Add(ed.AddMethod); - Add(ed.InvokeMethod); - Add(ed.RemoveMethod); - Add(ed.OtherMethods); - Add(ed.DeclaringType); - } - - void Add(IEnumerable fds) { - if (fds is null) - return; - foreach (var fd in fds) - Add(fd); - } - - void Add(FieldDef fd) { - if (fd is null || FieldDefs.ContainsKey(fd)) - return; - if (fd.DeclaringType is not null && fd.DeclaringType.Module != validModule) - return; - FieldDefs[fd] = true; - Add(fd.CustomAttributes); - Add(fd.Signature); - Add(fd.DeclaringType); - Add(fd.MarshalType); - } - - void Add(IEnumerable gps) { - if (gps is null) - return; - foreach (var gp in gps) - Add(gp); - } - - void Add(GenericParam gp) { - if (gp is null || GenericParams.ContainsKey(gp)) - return; - GenericParams[gp] = true; - Push(gp.Owner); - Push(gp.Kind); - Add(gp.GenericParamConstraints); - Add(gp.CustomAttributes); - } - - void Add(IEnumerable gpcs) { - if (gpcs is null) - return; - foreach (var gpc in gpcs) - Add(gpc); - } - - void Add(GenericParamConstraint gpc) { - if (gpc is null) - return; - Add(gpc.Owner); - Push(gpc.Constraint); - Add(gpc.CustomAttributes); - } - - void Add(MemberRef mr) { - if (mr is null || MemberRefs.ContainsKey(mr)) - return; - if (mr.Module != validModule) - return; - MemberRefs[mr] = true; - Push(mr.Class); - Add(mr.Signature); - Add(mr.CustomAttributes); - } - - void Add(IEnumerable methods) { - if (methods is null) - return; - foreach (var m in methods) - Add(m); - } - - void Add(MethodDef md) { - if (md is null || MethodDefs.ContainsKey(md)) - return; - if (md.DeclaringType is not null && md.DeclaringType.Module != validModule) - return; - MethodDefs[md] = true; - Add(md.Signature); - Add(md.ParamDefs); - Add(md.GenericParameters); - Add(md.DeclSecurities); - Add(md.MethodBody); - Add(md.CustomAttributes); - Add(md.Overrides); - Add(md.DeclaringType); - } - - void Add(MethodBody mb) { - if (mb is CilBody cb) - Add(cb); - } - - void Add(CilBody cb) { - if (cb is null) - return; - Add(cb.Instructions); - Add(cb.ExceptionHandlers); - Add(cb.Variables); - } - - void Add(IEnumerable instrs) { - if (instrs is null) - return; - foreach (var instr in instrs) { - if (instr is null) - continue; - switch (instr.OpCode.OperandType) { - case OperandType.InlineTok: - case OperandType.InlineType: - case OperandType.InlineMethod: - case OperandType.InlineField: - Push(instr.Operand); - break; - - case OperandType.InlineSig: - Add(instr.Operand as CallingConventionSig); - break; - - case OperandType.InlineVar: - case OperandType.ShortInlineVar: - var local = instr.Operand as Local; - if (local is not null) { - Add(local); - break; - } - var arg = instr.Operand as Parameter; - if (arg is not null) { - Add(arg); - break; - } - break; - } - } - } - - void Add(IEnumerable ehs) { - if (ehs is null) - return; - foreach (var eh in ehs) - Push(eh.CatchType); - } - - void Add(IEnumerable locals) { - if (locals is null) - return; - foreach (var local in locals) - Add(local); - } - - void Add(Local local) { - if (local is null) - return; - Add(local.Type); - } - - void Add(IEnumerable ps) { - if (ps is null) - return; - foreach (var p in ps) - Add(p); - } - - void Add(Parameter param) { - if (param is null) - return; - Add(param.Type); - Add(param.Method); - } - - void Add(IEnumerable pds) { - if (pds is null) - return; - foreach (var pd in pds) - Add(pd); - } - - void Add(ParamDef pd) { - if (pd is null) - return; - Add(pd.DeclaringMethod); - Add(pd.CustomAttributes); - Add(pd.MarshalType); - } - - void Add(MarshalType mt) { - if (mt is null) - return; - - switch (mt.NativeType) { - case NativeType.SafeArray: - Add(((SafeArrayMarshalType)mt).UserDefinedSubType); - break; - - case NativeType.CustomMarshaler: - Add(((CustomMarshalType)mt).CustomMarshaler); - break; - } - } - - void Add(IEnumerable mos) { - if (mos is null) - return; - foreach (var mo in mos) - Add(mo); - } - - void Add(MethodOverride mo) { - // It's a struct so can't be null - Push(mo.MethodBody); - Push(mo.MethodDeclaration); - } - - void Add(MethodSpec ms) { - if (ms is null || MethodSpecs.ContainsKey(ms)) - return; - if (ms.Method is not null && ms.Method.DeclaringType is not null && ms.Method.DeclaringType.Module != validModule) - return; - MethodSpecs[ms] = true; - Push(ms.Method); - Add(ms.Instantiation); - Add(ms.CustomAttributes); - } - - void Add(IEnumerable pds) { - if (pds is null) - return; - foreach (var pd in pds) - Add(pd); - } - - void Add(PropertyDef pd) { - if (pd is null || PropertyDefs.ContainsKey(pd)) - return; - if (pd.DeclaringType is not null && pd.DeclaringType.Module != validModule) - return; - PropertyDefs[pd] = true; - Add(pd.Type); - Add(pd.CustomAttributes); - Add(pd.GetMethods); - Add(pd.SetMethods); - Add(pd.OtherMethods); - Add(pd.DeclaringType); - } - - void Add(IEnumerable tds) { - if (tds is null) - return; - foreach (var td in tds) - Add(td); - } - - void Add(TypeDef td) { - if (td is null || TypeDefs.ContainsKey(td)) - return; - if (td.Module != validModule) - return; - TypeDefs[td] = true; - Push(td.BaseType); - Add(td.Fields); - Add(td.Methods); - Add(td.GenericParameters); - Add(td.Interfaces); - Add(td.DeclSecurities); - Add(td.DeclaringType); - Add(td.Events); - Add(td.Properties); - Add(td.NestedTypes); - Add(td.CustomAttributes); - } - - void Add(IEnumerable iis) { - if (iis is null) - return; - foreach (var ii in iis) - Add(ii); - } - - void Add(InterfaceImpl ii) { - if (ii is null) - return; - Push(ii.Interface); - Add(ii.CustomAttributes); - } - - void Add(TypeRef tr) { - if (tr is null || TypeRefs.ContainsKey(tr)) - return; - if (tr.Module != validModule) - return; - TypeRefs[tr] = true; - Push(tr.ResolutionScope); - Add(tr.CustomAttributes); - } - - void Add(IEnumerable tss) { - if (tss is null) - return; - foreach (var ts in tss) - Add(ts); - } - - void Add(TypeSig ts) { - if (ts is null || TypeSigs.ContainsKey(ts)) - return; - if (ts.Module != validModule) - return; - TypeSigs[ts] = true; - - for (; ts is not null; ts = ts.Next) { - switch (ts.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.ValueType: - case ElementType.Class: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - var tdrs = (TypeDefOrRefSig)ts; - Push(tdrs.TypeDefOrRef); - break; - - case ElementType.FnPtr: - var fps = (FnPtrSig)ts; - Add(fps.Signature); - break; - - case ElementType.GenericInst: - var gis = (GenericInstSig)ts; - Add(gis.GenericType); - Add(gis.GenericArguments); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - var ms = (ModifierSig)ts; - Push(ms.Modifier); - break; - - case ElementType.End: - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Var: - case ElementType.Array: - case ElementType.ValueArray: - case ElementType.R: - case ElementType.SZArray: - case ElementType.MVar: - case ElementType.Internal: - case ElementType.Module: - case ElementType.Sentinel: - case ElementType.Pinned: - default: - break; - } - } - } - - void Add(TypeSpec ts) { - if (ts is null || TypeSpecs.ContainsKey(ts)) - return; - if (ts.Module != validModule) - return; - TypeSpecs[ts] = true; - Add(ts.TypeSig); - Add(ts.CustomAttributes); - } - - void Add(IEnumerable ets) { - if (ets is null) - return; - foreach (var et in ets) - Add(et); - } - - void Add(ExportedType et) { - if (et is null || ExportedTypes.ContainsKey(et)) - return; - if (et.Module != validModule) - return; - ExportedTypes[et] = true; - Add(et.CustomAttributes); - Push(et.Implementation); - } - } -} diff --git a/Plugins/dnlib/DotNet/MemberMDInitializer.cs b/Plugins/dnlib/DotNet/MemberMDInitializer.cs deleted file mode 100644 index 93f1470..0000000 --- a/Plugins/dnlib/DotNet/MemberMDInitializer.cs +++ /dev/null @@ -1,29 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Methods to load properties to make sure they're initialized - /// - static class MemberMDInitializer { - /// - /// Read every collection element - /// - /// Collection element type - /// Collection - public static void Initialize(IEnumerable coll) { - if (coll is null) - return; - foreach (var c in coll) { - } - } - - /// - /// Load the object instance - /// - /// The value (ignored) - public static void Initialize(object o) { - } - } -} diff --git a/Plugins/dnlib/DotNet/MemberRef.cs b/Plugins/dnlib/DotNet/MemberRef.cs deleted file mode 100644 index 40842b2..0000000 --- a/Plugins/dnlib/DotNet/MemberRef.cs +++ /dev/null @@ -1,516 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the MemberRef table - /// - public abstract class MemberRef : IHasCustomAttribute, IMethodDefOrRef, ICustomAttributeType, IField, IContainsGenericParameter, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - - /// - /// The owner module - /// - protected ModuleDef module; - - /// - public MDToken MDToken => new MDToken(Table.MemberRef, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 6; - - /// - public int MethodDefOrRefTag => 1; - - /// - public int CustomAttributeTypeTag => 3; - - /// - /// From column MemberRef.Class - /// - public IMemberRefParent Class { - get => @class; - set => @class = value; - } - /// - protected IMemberRefParent @class; - - /// - /// From column MemberRef.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column MemberRef.Signature - /// - public CallingConventionSig Signature { - get => signature; - set => signature = value; - } - /// - protected CallingConventionSig signature; - - /// - /// 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 => 6; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 ITypeDefOrRef DeclaringType { - get { - var owner = @class; - - if (owner is ITypeDefOrRef tdr) - return tdr; - - if (owner is MethodDef method) - return method.DeclaringType; - - if (owner is ModuleRef mr) { - var tr = GetGlobalTypeRef(mr); - if (module is not null) - return module.UpdateRowId(tr); - return tr; - } - - return null; - } - } - - TypeRefUser GetGlobalTypeRef(ModuleRef mr) { - if (module is null) - return CreateDefaultGlobalTypeRef(mr); - var globalType = module.GlobalType; - 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) - return CreateDefaultGlobalTypeRef(mr); - var mod = asm.FindModule(mr.Name); - if (mod is null) - return CreateDefaultGlobalTypeRef(mr); - globalType = mod.GlobalType; - 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 is not null) - module.UpdateRowId(tr); - return tr; - } - - 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 => MethodSig is not null; - - /// - /// true if this is a field reference ( != null) - /// - public bool IsFieldRef => FieldSig is not null; - - /// - /// Gets/sets the method sig - /// - public MethodSig MethodSig { - get => signature as MethodSig; - set => signature = value; - } - - /// - /// Gets/sets the field sig - /// - public FieldSig FieldSig { - get => signature as FieldSig; - set => signature = value; - } - - /// - public ModuleDef Module => module; - - /// - /// true if the method has a hidden 'this' parameter - /// - public bool HasThis { - get { - var ms = MethodSig; - return ms is null ? false : ms.HasThis; - } - } - - /// - /// true if the method has an explicit 'this' parameter - /// - public bool ExplicitThis { - get { - var ms = MethodSig; - return ms is null ? false : ms.ExplicitThis; - } - } - - /// - /// Gets the calling convention - /// - public CallingConvention CallingConvention { - get { - var ms = MethodSig; - return ms is null ? 0 : ms.CallingConvention & CallingConvention.Mask; - } - } - - /// - /// Gets/sets the method return type - /// - public TypeSig ReturnType { - get => MethodSig?.RetType; - set { - var ms = MethodSig; - if (ms is not null) - ms.RetType = value; - } - } - - /// - int IGenericParameterProvider.NumberOfGenericParameters => (int)(MethodSig?.GenParamCount ?? 0); - - /// - /// Gets the full name - /// - public string FullName { - get { - var parent = @class; - IList typeGenArgs = null; - if (parent is TypeSpec) { - if (((TypeSpec)parent).TypeSig is GenericInstSig sig) - typeGenArgs = sig.GenericArguments; - } - var methodSig = MethodSig; - if (methodSig is not null) - return FullNameFactory.MethodFullName(GetDeclaringTypeFullName(parent), name, methodSig, typeGenArgs, null, null, null); - var fieldSig = FieldSig; - if (fieldSig is not null) - return FullNameFactory.FieldFullName(GetDeclaringTypeFullName(parent), name, fieldSig, typeGenArgs, null); - return string.Empty; - } - } - - /// - /// Get the declaring type's full name - /// - /// Full name or null if there's no declaring type - public string GetDeclaringTypeFullName() => GetDeclaringTypeFullName(@class); - - string GetDeclaringTypeFullName(IMemberRefParent parent) { - if (parent is null) - return null; - if (parent is ITypeDefOrRef) - return ((ITypeDefOrRef)parent).FullName; - if (parent is ModuleRef) - return $"[module:{((ModuleRef)parent).ToString()}]"; - if (parent is MethodDef) { - var declaringType = ((MethodDef)parent).DeclaringType; - 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 - /// - /// A or a instance or null - /// if it couldn't be resolved. - public IMemberForwarded Resolve() { - if (module is null) - return null; - return module.Context.Resolver.Resolve(this); - } - - /// - /// Resolves the method/field - /// - /// A or a instance - /// If the method/field couldn't be resolved - public IMemberForwarded ResolveThrow() { - var memberDef = Resolve(); - if (memberDef is not null) - return memberDef; - 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() => Resolve() as FieldDef; - - /// - /// Resolves the field - /// - /// A instance - /// If the field couldn't be resolved - public FieldDef ResolveFieldThrow() { - var field = ResolveField(); - if (field is not null) - return field; - 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() => Resolve() as MethodDef; - - /// - /// Resolves the method - /// - /// A instance - /// If the method couldn't be resolved - public MethodDef ResolveMethodThrow() { - var method = ResolveMethod(); - if (method is not null) - return method; - throw new MemberRefResolveException($"Could not resolve method: {this} ({this.GetDefinitionAssembly()})"); - } - - bool IContainsGenericParameter.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - /// Gets a that can be used as signature context - /// - /// Context passed to the constructor - /// Field/method class owner - /// - protected static GenericParamContext GetSignatureGenericParamContext(GenericParamContext gpContext, IMemberRefParent @class) { - TypeDef type = null; - var method = gpContext.Method; - - if (@class is TypeSpec ts && ts.TypeSig is GenericInstSig gis) - type = gis.GenericType.ToTypeDefOrRef().ResolveTypeDef(); - - return new GenericParamContext(type, method); - } - - /// - public override string ToString() => FullName; - } - - /// - /// A MemberRef row created by the user and not present in the original .NET file - /// - public class MemberRefUser : MemberRef { - /// - /// Constructor - /// - /// Owner module - public MemberRefUser(ModuleDef module) => this.module = module; - - /// - /// Constructor - /// - /// Owner module - /// Name of ref - public MemberRefUser(ModuleDef module, UTF8String name) { - this.module = module; - this.name = name; - } - - /// - /// Constructor - /// - /// Owner module - /// Name of field ref - /// Field sig - public MemberRefUser(ModuleDef module, UTF8String name, FieldSig sig) - : this(module, name, sig, null) { - } - - /// - /// Constructor - /// - /// Owner module - /// Name of field ref - /// Field sig - /// Owner of field - public MemberRefUser(ModuleDef module, UTF8String name, FieldSig sig, IMemberRefParent @class) { - this.module = module; - this.name = name; - this.@class = @class; - signature = sig; - } - - /// - /// Constructor - /// - /// Owner module - /// Name of method ref - /// Method sig - public MemberRefUser(ModuleDef module, UTF8String name, MethodSig sig) - : this(module, name, sig, null) { - } - - /// - /// Constructor - /// - /// Owner module - /// Name of method ref - /// Method sig - /// Owner of method - public MemberRefUser(ModuleDef module, UTF8String name, MethodSig sig, IMemberRefParent @class) { - this.module = module; - this.name = name; - this.@class = @class; - signature = sig; - } - } - - /// - /// Created from a row in the MemberRef table - /// - sealed class MemberRefMD : MemberRef, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - - /// - public uint OrigRid => origRid; - - bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.MemberRef, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this MemberRef row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public MemberRefMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.MemberRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"MemberRef rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - module = readerModule; - bool b = readerModule.TablesStream.TryReadMemberRefRow(origRid, out var row); - Debug.Assert(b); - name = readerModule.StringsStream.ReadNoNull(row.Name); - @class = readerModule.ResolveMemberRefParent(row.Class, gpContext); - signature = readerModule.ReadSignature(row.Signature, GetSignatureGenericParamContext(gpContext, @class)); - } - } -} diff --git a/Plugins/dnlib/DotNet/MethodAttributes.cs b/Plugins/dnlib/DotNet/MethodAttributes.cs deleted file mode 100644 index 3c66de8..0000000 --- a/Plugins/dnlib/DotNet/MethodAttributes.cs +++ /dev/null @@ -1,65 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Method attributes, see CorHdr.h/CorMethodAttr - /// - [Flags] - public enum MethodAttributes : ushort { - /// member access mask - Use this mask to retrieve accessibility information. - MemberAccessMask = 0x0007, - /// Member not referenceable. - PrivateScope = 0x0000, - /// Member not referenceable. - CompilerControlled = PrivateScope, - /// Accessible only by the parent type. - Private = 0x0001, - /// Accessible by sub-types only in this Assembly. - FamANDAssem = 0x0002, - /// Accessibly by anyone in the Assembly. - Assembly = 0x0003, - /// Accessible only by type and sub-types. - Family = 0x0004, - /// Accessibly by sub-types anywhere, plus anyone in assembly. - FamORAssem = 0x0005, - /// Accessibly by anyone who has visibility to this scope. - Public = 0x0006, - - /// Defined on type, else per instance. - Static = 0x0010, - /// Method may not be overridden. - Final = 0x0020, - /// Method virtual. - Virtual = 0x0040, - /// Method hides by name+sig, else just by name. - HideBySig = 0x0080, - - /// vtable layout mask - Use this mask to retrieve vtable attributes. - VtableLayoutMask = 0x0100, - /// The default. - ReuseSlot = 0x0000, - /// Method always gets a new slot in the vtable. - NewSlot = 0x0100, - - /// Overridability is the same as the visibility. - CheckAccessOnOverride = 0x0200, - /// Method does not provide an implementation. - Abstract = 0x0400, - /// Method is special. Name describes how. - SpecialName = 0x0800, - - /// Implementation is forwarded through pinvoke. - PinvokeImpl = 0x2000, - /// Managed method exported via thunk to unmanaged code. - UnmanagedExport = 0x0008, - - /// Runtime should check name encoding. - RTSpecialName = 0x1000, - /// Method has security associate with it. - HasSecurity = 0x4000, - /// Method calls another method containing security code. - RequireSecObject = 0x8000, - } -} diff --git a/Plugins/dnlib/DotNet/MethodDef.cs b/Plugins/dnlib/DotNet/MethodDef.cs deleted file mode 100644 index 9b58f7b..0000000 --- a/Plugins/dnlib/DotNet/MethodDef.cs +++ /dev/null @@ -1,1196 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Threading; -using dnlib.Utils; -using dnlib.PE; -using dnlib.DotNet.MD; -using dnlib.DotNet.Emit; -using dnlib.Threading; -using dnlib.DotNet.Pdb; -using System.Collections.Generic; -using System.Diagnostics; - -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, IHasCustomDebugInformation, IListListener, IListListener, IMemberDef { - internal static readonly UTF8String StaticConstructorName = ".cctor"; - internal static readonly UTF8String InstanceConstructorName = ".ctor"; - - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// All parameters - /// - protected ParameterList parameterList; - - /// - public MDToken MDToken => new MDToken(Table.Method, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 0; - - /// - public int HasDeclSecurityTag => 1; - - /// - public int MemberRefParentTag => 3; - - /// - public int MethodDefOrRefTag => 0; - - /// - public int MemberForwardedTag => 1; - - /// - public int CustomAttributeTypeTag => 2; - - /// - public int TypeOrMethodDefTag => 1; - - /// - /// From column Method.RVA - /// - public RVA RVA { - get => rva; - set => rva = value; - } - /// - protected RVA rva; - - /// - /// From column Method.ImplFlags - /// - public MethodImplAttributes ImplAttributes { - get => (MethodImplAttributes)implAttributes; - set => implAttributes = (int)value; - } - /// Implementation attributes - protected int implAttributes; - - /// - /// From column Method.Flags - /// - public MethodAttributes Attributes { - get => (MethodAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column Method.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column Method.Signature - /// - public CallingConventionSig Signature { - get => signature; - set => signature = value; - } - /// - protected CallingConventionSig signature; - - /// - /// From column Method.ParamList - /// - public IList ParamDefs { - get { - if (paramDefs is null) - InitializeParamDefs(); - return paramDefs; - } - } - /// - protected LazyList paramDefs; - /// Initializes - protected virtual void InitializeParamDefs() => - Interlocked.CompareExchange(ref paramDefs, new LazyList(this), null); - - /// - public IList GenericParameters { - get { - if (genericParameters is null) - InitializeGenericParameters(); - return genericParameters; - } - } - /// - protected LazyList genericParameters; - /// Initializes - protected virtual void InitializeGenericParameters() => - Interlocked.CompareExchange(ref genericParameters, new LazyList(this), null); - - /// - public IList DeclSecurities { - get { - if (declSecurities is null) - InitializeDeclSecurities(); - return declSecurities; - } - } - /// - protected IList declSecurities; - /// Initializes - protected virtual void InitializeDeclSecurities() => - Interlocked.CompareExchange(ref declSecurities, new List(), null); - - /// - public ImplMap ImplMap { - get { - if (!implMap_isInitialized) - InitializeImplMap(); - return implMap; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - implMap = value; - implMap_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected ImplMap implMap; - /// - protected bool implMap_isInitialized; - - void InitializeImplMap() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (implMap_isInitialized) - return; - implMap = GetImplMap_NoLock(); - implMap_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual ImplMap GetImplMap_NoLock() => null; - - /// Reset - protected void ResetImplMap() => implMap_isInitialized = false; - - /// - /// Gets/sets the method body. See also - /// - public MethodBody MethodBody { - get { - if (!methodBody_isInitialized) - InitializeMethodBody(); - return methodBody; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - methodBody = value; - methodBody_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected MethodBody methodBody; - /// - protected bool methodBody_isInitialized; - - void InitializeMethodBody() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (methodBody_isInitialized) - return; - methodBody = GetMethodBody_NoLock(); - methodBody_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Frees the method body if it has been loaded. This does nothing if - /// returns false. - /// - public void FreeMethodBody() { - if (!CanFreeMethodBody) - return; - if (!methodBody_isInitialized) - return; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - methodBody = null; - methodBody_isInitialized = false; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual MethodBody GetMethodBody_NoLock() => null; - - /// - /// true if can free the method body - /// - protected virtual bool CanFreeMethodBody => true; - - /// - /// 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 int HasCustomDebugInformationTag => 0; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Gets the methods this method implements - /// - public IList Overrides { - get { - if (overrides is null) - InitializeOverrides(); - return overrides; - } - } - /// - protected IList overrides; - /// Initializes - protected virtual void InitializeOverrides() => - Interlocked.CompareExchange(ref overrides, new List(), null); - - /// - /// Gets the export info or null if the method isn't exported to unmanaged code. - /// - public MethodExportInfo ExportInfo { - get => exportInfo; - set => exportInfo = value; - } - /// - protected MethodExportInfo exportInfo; - - /// - public bool HasCustomAttributes => CustomAttributes.Count > 0; - - /// - public bool HasDeclSecurities => DeclSecurities.Count > 0; - - /// - /// true if is not empty - /// - public bool HasParamDefs => ParamDefs.Count > 0; - - /// - /// Gets/sets the declaring type (owner type) - /// - public TypeDef DeclaringType { - get => declaringType2; - set { - var currentDeclaringType = DeclaringType2; - if (currentDeclaringType == value) - return; - if (currentDeclaringType is not null) - currentDeclaringType.Methods.Remove(this); // Will set DeclaringType2 = null - if (value is not null) - value.Methods.Add(this); // Will set DeclaringType2 = value - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; - - /// - /// Called by and should normally not be called by any user - /// code. Use instead. Only call this if you must set the - /// declaring type without inserting it in the declaring type's method list. - /// - public TypeDef DeclaringType2 { - get => declaringType2; - set => declaringType2 = value; - } - /// - protected TypeDef declaringType2; - - /// - 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 - /// - public CilBody Body { - get { - if (!methodBody_isInitialized) - InitializeMethodBody(); - return methodBody as CilBody; - } - set => MethodBody = value; - } - - /// - /// Gets/sets the native method body - /// - public NativeMethodBody NativeBody { - get { - if (!methodBody_isInitialized) - InitializeMethodBody(); - return methodBody as NativeMethodBody; - } - set => MethodBody = value; - } - - /// - /// true if there's at least one in - /// - public bool HasGenericParameters => GenericParameters.Count > 0; - - /// - /// true if it has a - /// - public bool HasBody => Body is not null; - - /// - /// true if there's at least one in - /// - public bool HasOverrides => Overrides.Count > 0; - - /// - /// true if is not null - /// - public bool HasImplMap => ImplMap is not null; - - /// - /// Gets the full name - /// - public string FullName => FullNameFactory.MethodFullName(declaringType2?.FullName, name, MethodSig, null, null, this, null); - - /// - /// Gets/sets the - /// - public MethodSig MethodSig { - get => signature as MethodSig; - set => signature = value; - } - - /// - /// Gets the parameters - /// - public ParameterList Parameters => parameterList; - - /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { - var sig = MethodSig; - return sig is null ? 0 : (int)sig.GenParamCount; - } - } - - /// - /// true if the method has a hidden 'this' parameter - /// - public bool HasThis { - get { - var ms = MethodSig; - return ms is null ? false : ms.HasThis; - } - } - - /// - /// true if the method has an explicit 'this' parameter - /// - public bool ExplicitThis { - get { - var ms = MethodSig; - return ms is null ? false : ms.ExplicitThis; - } - } - - /// - /// Gets the calling convention - /// - public CallingConvention CallingConvention { - get { - var ms = MethodSig; - return ms is null ? 0 : ms.CallingConvention & CallingConvention.Mask; - } - } - - /// - /// Gets/sets the method return type - /// - public TypeSig ReturnType { - get => MethodSig?.RetType; - set { - var ms = MethodSig; - if (ms is not null) - ms.RetType = value; - } - } - - /// - /// true if the method returns a value (i.e., return type is not ) - /// - public bool HasReturnType => ReturnType.RemovePinnedAndModifiers().GetElementType() != ElementType.Void; - - /// - /// Gets/sets the method semantics attributes. If you remove/add a method to a property or - /// an event, you must manually update this property or eg. won't - /// work as expected. - /// - public MethodSemanticsAttributes SemanticsAttributes { - get { - if ((semAttrs & SEMATTRS_INITD) == 0) - InitializeSemanticsAttributes(); - return (MethodSemanticsAttributes)semAttrs; - } - 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; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, MethodSemanticsAttributes flags) { - if ((semAttrs & SEMATTRS_INITD) == 0) - InitializeSemanticsAttributes(); - if (set) - semAttrs |= (int)flags; - else - semAttrs &= ~(int)flags; - } - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(MethodAttributes andMask, MethodAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, MethodAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyImplAttributes(MethodImplAttributes andMask, MethodImplAttributes orMask) => - implAttributes = (implAttributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyImplAttributes(bool set, MethodImplAttributes flags) { - if (set) - implAttributes |= (int)flags; - else - implAttributes &= ~(int)flags; - } - - /// - /// Gets/sets the method access - /// - public MethodAttributes Access { - get => (MethodAttributes)attributes & MethodAttributes.MemberAccessMask; - set => ModifyAttributes(~MethodAttributes.MemberAccessMask, value & MethodAttributes.MemberAccessMask); - } - - /// - /// true if is set - /// - public bool IsCompilerControlled => IsPrivateScope; - - /// - /// true if is set - /// - public bool IsPrivateScope => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.PrivateScope; - - /// - /// true if is set - /// - public bool IsPrivate => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Private; - - /// - /// true if is set - /// - public bool IsFamilyAndAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamANDAssem; - - /// - /// true if is set - /// - public bool IsAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Assembly; - - /// - /// true if is set - /// - public bool IsFamily => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Family; - - /// - /// true if is set - /// - public bool IsFamilyOrAssembly => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.FamORAssem; - - /// - /// true if is set - /// - public bool IsPublic => ((MethodAttributes)attributes & MethodAttributes.MemberAccessMask) == MethodAttributes.Public; - - /// - /// Gets/sets the bit - /// - public bool IsStatic { - get => ((MethodAttributes)attributes & MethodAttributes.Static) != 0; - set => ModifyAttributes(value, MethodAttributes.Static); - } - - /// - /// Gets/sets the bit - /// - public bool IsFinal { - get => ((MethodAttributes)attributes & MethodAttributes.Final) != 0; - set => ModifyAttributes(value, MethodAttributes.Final); - } - - /// - /// Gets/sets the bit - /// - public bool IsVirtual { - get => ((MethodAttributes)attributes & MethodAttributes.Virtual) != 0; - set => ModifyAttributes(value, MethodAttributes.Virtual); - } - - /// - /// Gets/sets the bit - /// - public bool IsHideBySig { - get => ((MethodAttributes)attributes & MethodAttributes.HideBySig) != 0; - set => ModifyAttributes(value, MethodAttributes.HideBySig); - } - - /// - /// Gets/sets the bit - /// - public bool IsNewSlot { - get => ((MethodAttributes)attributes & MethodAttributes.NewSlot) != 0; - set => ModifyAttributes(value, MethodAttributes.NewSlot); - } - - /// - /// Gets/sets the bit - /// - public bool IsReuseSlot { - get => ((MethodAttributes)attributes & MethodAttributes.NewSlot) == 0; - set => ModifyAttributes(!value, MethodAttributes.NewSlot); - } - - /// - /// Gets/sets the bit - /// - public bool IsCheckAccessOnOverride { - get => ((MethodAttributes)attributes & MethodAttributes.CheckAccessOnOverride) != 0; - set => ModifyAttributes(value, MethodAttributes.CheckAccessOnOverride); - } - - /// - /// Gets/sets the bit - /// - public bool IsAbstract { - get => ((MethodAttributes)attributes & MethodAttributes.Abstract) != 0; - set => ModifyAttributes(value, MethodAttributes.Abstract); - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((MethodAttributes)attributes & MethodAttributes.SpecialName) != 0; - set => ModifyAttributes(value, MethodAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsPinvokeImpl { - get => ((MethodAttributes)attributes & MethodAttributes.PinvokeImpl) != 0; - set => ModifyAttributes(value, MethodAttributes.PinvokeImpl); - } - - /// - /// Gets/sets the bit - /// - public bool IsUnmanagedExport { - get => ((MethodAttributes)attributes & MethodAttributes.UnmanagedExport) != 0; - set => ModifyAttributes(value, MethodAttributes.UnmanagedExport); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((MethodAttributes)attributes & MethodAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, MethodAttributes.RTSpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool HasSecurity { - get => ((MethodAttributes)attributes & MethodAttributes.HasSecurity) != 0; - set => ModifyAttributes(value, MethodAttributes.HasSecurity); - } - - /// - /// Gets/sets the bit - /// - public bool IsRequireSecObject { - get => ((MethodAttributes)attributes & MethodAttributes.RequireSecObject) != 0; - set => ModifyAttributes(value, MethodAttributes.RequireSecObject); - } - - /// - /// Gets/sets the code type - /// - public MethodImplAttributes CodeType { - get => (MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask; - set => ModifyImplAttributes(~MethodImplAttributes.CodeTypeMask, value & MethodImplAttributes.CodeTypeMask); - } - - /// - /// true if is set - /// - public bool IsIL => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.IL; - - /// - /// true if is set - /// - public bool IsNative => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Native; - - /// - /// true if is set - /// - public bool IsOPTIL => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.OPTIL; - - /// - /// true if is set - /// - public bool IsRuntime => ((MethodImplAttributes)implAttributes & MethodImplAttributes.CodeTypeMask) == MethodImplAttributes.Runtime; - - /// - /// Gets/sets the bit - /// - public bool IsUnmanaged { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.Unmanaged); - } - - /// - /// Gets/sets the bit - /// - public bool IsManaged { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Unmanaged) == 0; - set => ModifyImplAttributes(!value, MethodImplAttributes.Unmanaged); - } - - /// - /// Gets/sets the bit - /// - public bool IsForwardRef { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.ForwardRef) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.ForwardRef); - } - - /// - /// Gets/sets the bit - /// - public bool IsPreserveSig { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.PreserveSig) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.PreserveSig); - } - - /// - /// Gets/sets the bit - /// - public bool IsInternalCall { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.InternalCall) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.InternalCall); - } - - /// - /// Gets/sets the bit - /// - public bool IsSynchronized { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.Synchronized) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.Synchronized); - } - - /// - /// Gets/sets the bit - /// - public bool IsNoInlining { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoInlining) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.NoInlining); - } - - /// - /// Gets/sets the bit - /// - public bool IsAggressiveInlining { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.AggressiveInlining) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.AggressiveInlining); - } - - /// - /// Gets/sets the bit - /// - public bool IsNoOptimization { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.NoOptimization) != 0; - 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 - /// - public bool HasSecurityMitigations { - get => ((MethodImplAttributes)implAttributes & MethodImplAttributes.SecurityMitigations) != 0; - set => ModifyImplAttributes(value, MethodImplAttributes.SecurityMitigations); - } - - /// - /// Gets/sets the bit - /// - public bool IsSetter { - get => (SemanticsAttributes & MethodSemanticsAttributes.Setter) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.Setter); - } - - /// - /// Gets/sets the bit - /// - public bool IsGetter { - get => (SemanticsAttributes & MethodSemanticsAttributes.Getter) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.Getter); - } - - /// - /// Gets/sets the bit - /// - public bool IsOther { - get => (SemanticsAttributes & MethodSemanticsAttributes.Other) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.Other); - } - - /// - /// Gets/sets the bit - /// - public bool IsAddOn { - get => (SemanticsAttributes & MethodSemanticsAttributes.AddOn) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.AddOn); - } - - /// - /// Gets/sets the bit - /// - public bool IsRemoveOn { - get => (SemanticsAttributes & MethodSemanticsAttributes.RemoveOn) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.RemoveOn); - } - - /// - /// Gets/sets the bit - /// - public bool IsFire { - get => (SemanticsAttributes & MethodSemanticsAttributes.Fire) != 0; - set => ModifyAttributes(value, MethodSemanticsAttributes.Fire); - } - - /// - /// true if this is the static type constructor - /// - public bool IsStaticConstructor => IsRuntimeSpecialName && UTF8String.Equals(name, StaticConstructorName); - - /// - /// true if this is an instance constructor - /// - public bool IsInstanceConstructor => IsRuntimeSpecialName && UTF8String.Equals(name, InstanceConstructorName); - - /// - /// true if this is a static or an instance constructor - /// - public bool IsConstructor => IsStaticConstructor || IsInstanceConstructor; - - /// - void IListListener.OnLazyAdd(int index, ref GenericParam value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref GenericParam value) { -#if DEBUG - if (value.Owner != this) - throw new InvalidOperationException("Added generic param's Owner != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, GenericParam value) { - 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; - } - - /// - void IListListener.OnRemove(int index, GenericParam value) => value.Owner = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var gp in genericParameters.GetEnumerable_NoLock()) - gp.Owner = null; - } - - /// - void IListListener.OnLazyAdd(int index, ref ParamDef value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref ParamDef value) { -#if DEBUG - if (value.DeclaringMethod != this) - throw new InvalidOperationException("Added param's DeclaringMethod != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, ParamDef value) { - if (value.DeclaringMethod is not null) - throw new InvalidOperationException("Param is already owned by another method. Set DeclaringMethod to null first."); - value.DeclaringMethod = this; - } - - /// - void IListListener.OnRemove(int index, ParamDef value) => value.DeclaringMethod = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var pd in paramDefs.GetEnumerable_NoLock()) - pd.DeclaringMethod = null; - } - - /// - public override string ToString() => FullName; - } - - /// - /// A Method row created by the user and not present in the original .NET file - /// - public class MethodDefUser : MethodDef { - /// - /// Default constructor - /// - public MethodDefUser() { - paramDefs = new LazyList(this); - genericParameters = new LazyList(this); - parameterList = new ParameterList(this, null); - semAttrs = 0 | SEMATTRS_INITD; - } - - /// - /// Constructor - /// - /// Method name - public MethodDefUser(UTF8String name) - : this(name, null, 0, 0) { - } - - /// - /// Constructor - /// - /// Method name - /// Method sig - public MethodDefUser(UTF8String name, MethodSig methodSig) - : this(name, methodSig, 0, 0) { - } - - /// - /// Constructor - /// - /// Method name - /// Method sig - /// Flags - public MethodDefUser(UTF8String name, MethodSig methodSig, MethodAttributes flags) - : this(name, methodSig, 0, flags) { - } - - /// - /// Constructor - /// - /// Method name - /// Method sig - /// Impl flags - public MethodDefUser(UTF8String name, MethodSig methodSig, MethodImplAttributes implFlags) - : this(name, methodSig, implFlags, 0) { - } - - /// - /// Constructor - /// - /// Method name - /// Method sig - /// Impl flags - /// Flags - public MethodDefUser(UTF8String name, MethodSig methodSig, MethodImplAttributes implFlags, MethodAttributes flags) { - this.name = name; - 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; - } - } - - /// - /// Created from a row in the Method table - /// - sealed class MethodDefMD : MethodDef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly RVA origRva; - readonly MethodImplAttributes origImplAttributes; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeParamDefs() { - var list = readerModule.Metadata.GetParamRidList(origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveParam(list2[index])); - Interlocked.CompareExchange(ref paramDefs, tmp, null); - } - - /// - protected override void InitializeGenericParameters() { - var list = readerModule.Metadata.GetGenericParamRidList(Table.Method, origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveGenericParam(list2[index])); - Interlocked.CompareExchange(ref genericParameters, tmp, null); - } - - /// - protected override void InitializeDeclSecurities() { - var list = readerModule.Metadata.GetDeclSecurityRidList(Table.Method, origRid); - var tmp = new LazyList(list.Count, list, (list2, index) => readerModule.ResolveDeclSecurity(list2[index])); - Interlocked.CompareExchange(ref declSecurities, tmp, null); - } - - /// - protected override ImplMap GetImplMap_NoLock() => readerModule.ResolveImplMap(readerModule.Metadata.GetImplMapRid(Table.Method, origRid)); - - /// - protected override MethodBody GetMethodBody_NoLock() => readerModule.ReadMethodBody(this, origRva, origImplAttributes, new GenericParamContext(declaringType2, this)); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.Method, 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(); - if (Interlocked.CompareExchange(ref customDebugInfos, list, null) is null) { - var body = Body; - readerModule.InitializeCustomDebugInfos(this, body, list); - } - } - - /// - protected override void InitializeOverrides() { - var dt = declaringType2 as TypeDefMD; - var tmp = dt is null ? new List() : dt.GetMethodOverrides(this, new GenericParamContext(declaringType2, this)); - Interlocked.CompareExchange(ref overrides, tmp, null); - } - - /// - protected override void InitializeSemanticsAttributes() { - if (DeclaringType is TypeDefMD dt) - dt.InitializeMethodSemanticsAttributes(); - semAttrs |= SEMATTRS_INITD; - } - - /// - /// Constructor - /// - /// The module which contains this Method row - /// Row ID - /// If is null - /// If is invalid - public MethodDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.MethodTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Method rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadMethodRow(origRid, out var row); - Debug.Assert(b); - rva = (RVA)row.RVA; - implAttributes = row.ImplFlags; - attributes = row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - origRva = rva; - origImplAttributes = (MethodImplAttributes)implAttributes; - declaringType2 = readerModule.GetOwnerType(this); - signature = readerModule.ReadSignature(row.Signature, new GenericParamContext(declaringType2, this)); - parameterList = new ParameterList(this, declaringType2); - exportInfo = readerModule.GetExportInfo(rid); - } - - internal MethodDefMD InitializeAll() { - MemberMDInitializer.Initialize(RVA); - MemberMDInitializer.Initialize(Attributes); - MemberMDInitializer.Initialize(ImplAttributes); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(Signature); - MemberMDInitializer.Initialize(ImplMap); - MemberMDInitializer.Initialize(MethodBody); - MemberMDInitializer.Initialize(DeclaringType); - MemberMDInitializer.Initialize(CustomAttributes); - MemberMDInitializer.Initialize(Overrides); - MemberMDInitializer.Initialize(ParamDefs); - MemberMDInitializer.Initialize(GenericParameters); - MemberMDInitializer.Initialize(DeclSecurities); - return this; - } - - /// - internal override void OnLazyAdd2(int index, ref GenericParam value) { - if (value.Owner != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadGenericParam(value.Rid).InitializeAll()); - value.Owner = this; - } - } - - /// - internal override void OnLazyAdd2(int index, ref ParamDef value) { - if (value.DeclaringMethod != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadParam(value.Rid).InitializeAll()); - value.DeclaringMethod = this; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/MethodExportInfo.cs b/Plugins/dnlib/DotNet/MethodExportInfo.cs deleted file mode 100644 index 3a22aee..0000000 --- a/Plugins/dnlib/DotNet/MethodExportInfo.cs +++ /dev/null @@ -1,115 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -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 => 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 => name; - set => name = value; - } - - /// - /// Gets the options - /// - public MethodExportInfoOptions Options { - get => 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 - /// - [Flags] - 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/Plugins/dnlib/DotNet/MethodExportInfoProvider.cs b/Plugins/dnlib/DotNet/MethodExportInfoProvider.cs deleted file mode 100644 index 592f45f..0000000 --- a/Plugins/dnlib/DotNet/MethodExportInfoProvider.cs +++ /dev/null @@ -1,153 +0,0 @@ -// 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; - -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; - - if (!CpuArch.TryGetCpuArch(peImage.ImageNTHeaders.FileHeader.Machine, out var cpuArch)) { - Debug.Fail($"Exported methods: Unsupported machine: {peImage.ImageNTHeaders.FileHeader.Machine}"); - return; - } - - var reader = peImage.CreateReader(); - var offsetToInfo = GetOffsetToExportInfoDictionary(ref reader, peImage, exportHdr, cpuArch); - reader.Position = (uint)peImage.ToFileOffset(vtblHdr.VirtualAddress); - ulong endPos = (ulong)reader.Position + vtblHdr.Size; - while ((ulong)reader.Position + 8 <= endPos && reader.CanRead(8U)) { - var tableRva = (RVA)reader.ReadUInt32(); - int numSlots = reader.ReadUInt16(); - var flags = (VTableFlags)reader.ReadUInt16(); - bool is64bit = (flags & VTableFlags.Bit64) != 0; - var exportOptions = ToMethodExportInfoOptions(flags); - - var pos = reader.Position; - reader.Position = (uint)peImage.ToFileOffset(tableRva); - uint slotSize = is64bit ? 8U : 4; - while (numSlots-- > 0 && reader.CanRead(slotSize)) { - var tokenPos = reader.Position; - uint token = reader.ReadUInt32(); - if (offsetToInfo.TryGetValue(tokenPos, out var exportInfo)) - toInfo[token] = new MethodExportInfo(exportInfo.Name, exportInfo.Ordinal, exportOptions); - 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(ref DataReader reader, IPEImage peImage, ImageDataDirectory exportHdr, CpuArch cpuArch) { - reader.Position = (uint)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(); - uint offsetOfFuncs = (uint)peImage.ToFileOffset((RVA)reader.ReadUInt32()); - uint offsetOfNames = (uint)peImage.ToFileOffset((RVA)reader.ReadUInt32()); - uint offsetOfNameIndexes = (uint)peImage.ToFileOffset((RVA)reader.ReadUInt32()); - - var names = ReadNames(ref 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 nextOffset = reader.Position + 4; - uint funcRva = 0; - var rva = (RVA)reader.ReadUInt32(); - reader.Position = (uint)peImage.ToFileOffset(rva); - bool rvaValid = rva != 0 && cpuArch.TryGetExportedRvaFromStub(ref reader, peImage, out funcRva); - uint funcOffset = rvaValid ? (uint)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(ref DataReader reader, IPEImage peImage, int numNames, uint offsetOfNames, uint 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; - uint offsetOfName = (uint)peImage.ToFileOffset((RVA)reader.ReadUInt32()); - names[i].Name = ReadMethodNameASCIIZ(ref 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(ref DataReader reader, uint offset) { - reader.Position = offset; - return reader.TryReadZeroTerminatedUtf8String() ?? string.Empty; - } - - public MethodExportInfo GetMethodExportInfo(uint token) { - if (toInfo.Count == 0) - return null; - if (toInfo.TryGetValue(token, out var info)) - return new MethodExportInfo(info.Name, info.Ordinal, info.Options); - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/MethodImplAttributes.cs b/Plugins/dnlib/DotNet/MethodImplAttributes.cs deleted file mode 100644 index b1d3b3a..0000000 --- a/Plugins/dnlib/DotNet/MethodImplAttributes.cs +++ /dev/null @@ -1,50 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Method impl attributes, see CorHdr.h/CorMethodImpl - /// - [Flags] - public enum MethodImplAttributes : ushort { - /// Flags about code type. - CodeTypeMask = 0x0003, - /// Method impl is IL. - IL = 0x0000, - /// Method impl is native. - Native = 0x0001, - /// Method impl is OPTIL - OPTIL = 0x0002, - /// Method impl is provided by the runtime. - Runtime = 0x0003, - - /// Flags specifying whether the code is managed or unmanaged. - ManagedMask = 0x0004, - /// Method impl is unmanaged, otherwise managed. - Unmanaged = 0x0004, - /// Method impl is managed. - Managed = 0x0000, - - /// Indicates method is defined; used primarily in merge scenarios. - ForwardRef = 0x0010, - /// Indicates method sig is not to be mangled to do HRESULT conversion. - PreserveSig = 0x0080, - - /// Reserved for internal use. - InternalCall = 0x1000, - - /// Method is single threaded through the body. - Synchronized = 0x0020, - /// Method may not be inlined. - NoInlining = 0x0008, - /// Method should be inlined if possible. - AggressiveInlining = 0x0100, - /// Method may not be optimized. - 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, - } -} diff --git a/Plugins/dnlib/DotNet/MethodOverride.cs b/Plugins/dnlib/DotNet/MethodOverride.cs deleted file mode 100644 index 901ed60..0000000 --- a/Plugins/dnlib/DotNet/MethodOverride.cs +++ /dev/null @@ -1,28 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Describes which method some method implements - /// - public struct MethodOverride { - /// - /// The method body. Usually a but could be a - /// - public IMethodDefOrRef MethodBody; - - /// - /// The method implements - /// - public IMethodDefOrRef MethodDeclaration; - - /// - /// Constructor - /// - /// Method body - /// The method implements - public MethodOverride(IMethodDefOrRef methodBody, IMethodDefOrRef methodDeclaration) { - MethodBody = methodBody; - MethodDeclaration = methodDeclaration; - } - } -} diff --git a/Plugins/dnlib/DotNet/MethodSemanticsAttributes.cs b/Plugins/dnlib/DotNet/MethodSemanticsAttributes.cs deleted file mode 100644 index 488e92e..0000000 --- a/Plugins/dnlib/DotNet/MethodSemanticsAttributes.cs +++ /dev/null @@ -1,26 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Method semantics flags, see CorHdr.h/CorMethodSemanticsAttr - /// - [Flags] - public enum MethodSemanticsAttributes : ushort { - /// No bit is set - None = 0, - /// Setter for property - Setter = 0x0001, - /// Getter for property - Getter = 0x0002, - /// other method for property or event - Other = 0x0004, - /// AddOn method for event - AddOn = 0x0008, - /// RemoveOn method for event - RemoveOn = 0x0010, - /// Fire method for event - Fire = 0x0020, - } -} diff --git a/Plugins/dnlib/DotNet/MethodSpec.cs b/Plugins/dnlib/DotNet/MethodSpec.cs deleted file mode 100644 index de3393a..0000000 --- a/Plugins/dnlib/DotNet/MethodSpec.cs +++ /dev/null @@ -1,258 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the MethodSpec table - /// - public abstract class MethodSpec : IHasCustomAttribute, IHasCustomDebugInformation, IMethod, IContainsGenericParameter { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.MethodSpec, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 21; - - /// - /// From column MethodSpec.Method - /// - public IMethodDefOrRef Method { - get => method; - set => method = value; - } - /// - protected IMethodDefOrRef method; - - /// - /// From column MethodSpec.Instantiation - /// - public CallingConventionSig Instantiation { - get => instantiation; - set => instantiation = value; - } - /// - protected CallingConventionSig instantiation; - - /// - /// 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 => 21; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - MethodSig IMethod.MethodSig { - get => method?.MethodSig; - set { - var m = method; - if (m is not null) - m.MethodSig = value; - } - } - - /// - public UTF8String Name { - get { - var m = method; - return m is null ? UTF8String.Empty : m.Name; - } - set { - var m = method; - if (m is not null) - m.Name = value; - } - } - - /// - public ITypeDefOrRef DeclaringType => method?.DeclaringType; - - /// - /// Gets/sets the generic instance method sig - /// - public GenericInstMethodSig GenericInstMethodSig { - get => instantiation as GenericInstMethodSig; - set => instantiation = value; - } - - /// - int IGenericParameterProvider.NumberOfGenericParameters => GenericInstMethodSig?.GenericArguments.Count ?? 0; - - /// - public ModuleDef Module => method?.Module; - - /// - /// Gets the full name - /// - public string FullName { - get { - var methodGenArgs = GenericInstMethodSig?.GenericArguments; - var m = method; - if (m is MethodDef methodDef) - 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 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); - } - } - - return string.Empty; - } - } - - 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() => FullName; - } - - /// - /// A MethodSpec row created by the user and not present in the original .NET file - /// - public class MethodSpecUser : MethodSpec { - /// - /// Default constructor - /// - public MethodSpecUser() { - } - - /// - /// Constructor - /// - /// The generic method - public MethodSpecUser(IMethodDefOrRef method) - : this(method, null) { - } - - /// - /// Constructor - /// - /// The generic method - /// The instantiated method sig - public MethodSpecUser(IMethodDefOrRef method, GenericInstMethodSig sig) { - this.method = method; - instantiation = sig; - } - } - - /// - /// Created from a row in the MethodSpec table - /// - sealed class MethodSpecMD : MethodSpec, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - - /// - public uint OrigRid => origRid; - - bool IContainsGenericParameter2.ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.MethodSpec, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this MethodSpec row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public MethodSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.MethodSpecTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"MethodSpec rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - bool b = readerModule.TablesStream.TryReadMethodSpecRow(origRid, out var row); - Debug.Assert(b); - method = readerModule.ResolveMethodDefOrRef(row.Method, gpContext); - instantiation = readerModule.ReadSignature(row.Instantiation, gpContext); - } - } -} diff --git a/Plugins/dnlib/DotNet/ModuleContext.cs b/Plugins/dnlib/DotNet/ModuleContext.cs deleted file mode 100644 index b0ccfe0..0000000 --- a/Plugins/dnlib/DotNet/ModuleContext.cs +++ /dev/null @@ -1,102 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Threading; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet { - /// - /// context - /// - public class ModuleContext { - IAssemblyResolver assemblyResolver; - IResolver resolver; - readonly OpCode[][] experimentalOpCodes = new OpCode[12][]; - - /// - /// Gets/sets the assembly resolver. This is never null. - /// - public IAssemblyResolver AssemblyResolver { - get { - if (assemblyResolver is null) - Interlocked.CompareExchange(ref assemblyResolver, NullResolver.Instance, null); - return assemblyResolver; - } - set => assemblyResolver = value; - } - - /// - /// Gets/sets the resolver. This is never null. - /// - public IResolver Resolver { - get { - if (resolver is null) - Interlocked.CompareExchange(ref resolver, NullResolver.Instance, null); - return resolver; - } - set => resolver = value; - } - - /// - /// Default constructor - /// - public ModuleContext() { - } - - /// - /// Constructor - /// - /// Assembly resolver or null - public ModuleContext(IAssemblyResolver assemblyResolver) - : this(assemblyResolver, new Resolver(assemblyResolver)) { - } - - /// - /// Constructor - /// - /// Type/method/field resolver or null - public ModuleContext(IResolver resolver) - : this(null, resolver) { - } - - /// - /// Constructor - /// - /// Assembly resolver or null - /// Type/method/field resolver or null - public ModuleContext(IAssemblyResolver assemblyResolver, IResolver resolver) { - this.assemblyResolver = assemblyResolver; - this.resolver = resolver; - if (resolver is null && assemblyResolver is not 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/Plugins/dnlib/DotNet/ModuleCreationOptions.cs b/Plugins/dnlib/DotNet/ModuleCreationOptions.cs deleted file mode 100644 index dc0020f..0000000 --- a/Plugins/dnlib/DotNet/ModuleCreationOptions.cs +++ /dev/null @@ -1,95 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// creation options - /// - public sealed class ModuleCreationOptions { - internal static readonly ModuleCreationOptions Default = new ModuleCreationOptions(); - - /// - /// Module context - /// - public ModuleContext Context { get; set; } - - internal const PdbReaderOptions DefaultPdbReaderOptions = PdbReaderOptions.None; - - /// - /// PDB reader options - /// - 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 - /// C) to an of the PDB data. The will - /// be owned by the module. You don't need to initialize - /// - 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 . - /// - public bool TryToLoadPdbFromDisk { get; set; } = true; - - /// - /// corlib assembly reference to use or null if the default one from the opened - /// module should be used. - /// - 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 - /// - public ModuleCreationOptions() { } - - /// - /// Constructor - /// - /// 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/Plugins/dnlib/DotNet/ModuleDef.cs b/Plugins/dnlib/DotNet/ModuleDef.cs deleted file mode 100644 index 4fe5bbc..0000000 --- a/Plugins/dnlib/DotNet/ModuleDef.cs +++ /dev/null @@ -1,1558 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Reflection; -using System.Threading; -using dnlib.Utils; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.DotNet.Writer; -using dnlib.PE; -using dnlib.Threading; -using dnlib.W32Resources; -using System.Diagnostics; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Module table - /// - public abstract class ModuleDef : IHasCustomAttribute, IHasCustomDebugInformation, IResolutionScope, IDisposable, IListListener, IModule, ITypeDefFinder, IDnlibDef, ITokenResolver, ISignatureReaderHelper { - /// Default characteristics - protected const Characteristics DefaultCharacteristics = Characteristics.ExecutableImage | Characteristics.Bit32Machine; - - /// Default DLL characteristics - protected const DllCharacteristics DefaultDllCharacteristics = DllCharacteristics.TerminalServerAware | DllCharacteristics.NoSeh | DllCharacteristics.NxCompat | DllCharacteristics.DynamicBase; - - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// Initialize this in the ctor - /// - protected ICorLibTypes corLibTypes; - - /// - /// PDB state - /// - protected PdbState pdbState; - - TypeDefFinder typeDefFinder; - - /// - /// Array of last used rid in each table. I.e., next free rid is value + 1 - /// - protected readonly int[] lastUsedRids = new int[64]; - - /// Module context - protected ModuleContext context; - - /// - public MDToken MDToken => new MDToken(Table.Module, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 7; - - /// - 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 => tag; - set => tag = value; - } - object tag; - - /// - public ScopeType ScopeType => ScopeType.ModuleDef; - - /// - public string ScopeName => FullName; - - /// - /// Gets/sets Module.Generation column - /// - public ushort Generation { - get => generation; - set => generation = value; - } - /// - protected ushort generation; - - /// - /// Gets/sets Module.Name column - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// Gets/sets Module.Mvid column - /// - public Guid? Mvid { - get => mvid; - set => mvid = value; - } - /// - protected Guid? mvid; - - /// - /// Gets/sets Module.EncId column - /// - public Guid? EncId { - get => encId; - set => encId = value; - } - /// - protected Guid? encId; - - /// - /// Gets/sets Module.EncBaseId column - /// - public Guid? EncBaseId { - get => encBaseId; - set => encBaseId = value; - } - /// - protected Guid? encBaseId; - - /// - /// 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 int HasCustomDebugInformationTag => 7; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Gets the module's assembly. To set this value, add this - /// to . - /// - public AssemblyDef Assembly { - get => assembly; - internal set => assembly = value; - } - /// - protected AssemblyDef assembly; - - /// - /// Gets a list of all non-nested s. See also - /// - public IList Types { - get { - if (types is null) - InitializeTypes(); - return types; - } - } - /// - protected LazyList types; - /// Initializes - protected virtual void InitializeTypes() => - Interlocked.CompareExchange(ref types, new LazyList(this), null); - - /// - /// Gets a list of all s - /// - public IList ExportedTypes { - get { - if (exportedTypes is null) - InitializeExportedTypes(); - return exportedTypes; - } - } - /// - protected IList exportedTypes; - /// Initializes - protected virtual void InitializeExportedTypes() => - Interlocked.CompareExchange(ref exportedTypes, new List(), null); - - /// - /// Gets/sets the native entry point. Only one of and - /// can be set. You write to one and the other one gets cleared. - /// - public RVA NativeEntryPoint { - get { - if (!nativeAndManagedEntryPoint_initialized) - InitializeNativeAndManagedEntryPoint(); - return nativeEntryPoint; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - nativeEntryPoint = value; - managedEntryPoint = null; - Cor20HeaderFlags |= ComImageFlags.NativeEntryPoint; - nativeAndManagedEntryPoint_initialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - /// Gets/sets the managed entry point. Only one of and - /// can be set. You write to one and the other one gets cleared. - /// - public IManagedEntryPoint ManagedEntryPoint { - get { - if (!nativeAndManagedEntryPoint_initialized) - InitializeNativeAndManagedEntryPoint(); - return managedEntryPoint; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - nativeEntryPoint = 0; - managedEntryPoint = value; - Cor20HeaderFlags &= ~ComImageFlags.NativeEntryPoint; - nativeAndManagedEntryPoint_initialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected RVA nativeEntryPoint; - /// - protected IManagedEntryPoint managedEntryPoint; - /// - protected bool nativeAndManagedEntryPoint_initialized; - - void InitializeNativeAndManagedEntryPoint() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (nativeAndManagedEntryPoint_initialized) - return; - nativeEntryPoint = GetNativeEntryPoint_NoLock(); - managedEntryPoint = GetManagedEntryPoint_NoLock(); - nativeAndManagedEntryPoint_initialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - /// Called to initialize - protected virtual RVA GetNativeEntryPoint_NoLock() => 0; - /// Called to initialize - protected virtual IManagedEntryPoint GetManagedEntryPoint_NoLock() => null; - - /// - public bool HasCustomAttributes => CustomAttributes.Count > 0; - - /// - /// Gets/sets the entry point method - /// - public MethodDef EntryPoint { - get => ManagedEntryPoint as MethodDef; - set => ManagedEntryPoint = value; - } - - /// - /// true if is non-zero - /// - public bool IsNativeEntryPointValid => NativeEntryPoint != 0; - - /// - /// true if is non-null - /// - public bool IsManagedEntryPointValid => ManagedEntryPoint is not null; - - /// - /// true if is non-null - /// - public bool IsEntryPointValid => EntryPoint is not null; - - /// - /// Gets a list of all s - /// - public ResourceCollection Resources { - get { - if (resources is null) - InitializeResources(); - return resources; - } - } - /// - protected ResourceCollection resources; - /// Initializes - protected virtual void InitializeResources() => - Interlocked.CompareExchange(ref resources, new ResourceCollection(), null); - - /// - /// Gets/sets the . This is null if there are no - /// vtable fixups. - /// - public VTableFixups VTableFixups { - get { - if (!vtableFixups_isInitialized) - InitializeVTableFixups(); - return vtableFixups; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - vtableFixups = value; - vtableFixups_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected VTableFixups vtableFixups; - /// - protected bool vtableFixups_isInitialized; - - void InitializeVTableFixups() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (vtableFixups_isInitialized) - return; - vtableFixups = GetVTableFixups_NoLock(); - vtableFixups_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual VTableFixups GetVTableFixups_NoLock() => null; - - /// - /// true if there's at least one in - /// - public bool HasTypes => Types.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasExportedTypes => ExportedTypes.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasResources => Resources.Count > 0; - - /// - 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 => location; - set => location = value; - } - /// - protected string location; - - /// - /// Gets the - /// - public ICorLibTypes CorLibTypes => corLibTypes; - - /// - /// Gets the instance - /// - TypeDefFinder TypeDefFinder { - get { - if (typeDefFinder is null) - Interlocked.CompareExchange(ref typeDefFinder, new TypeDefFinder(Types), null); - return typeDefFinder; - } - } - - /// - /// Gets/sets the module context. This is never null. - /// - public ModuleContext Context { - get { - if (context is null) - Interlocked.CompareExchange(ref context, new ModuleContext(), null); - return context; - } - set => context = value ?? new ModuleContext(); - } - - /// - /// If true, the cache is enabled. The cache is used by - /// and to find types. - ///

- /// IMPORTANT: Only enable the cache if this module's types keep their exact - /// name, namespace, and declaring type and if no type is either added or - /// removed from or from any type that is reachable from the - /// top-level types in (i.e., any type owned by this module). - /// This is disabled by default. When disabled, all calls to - /// and will result in a slow O(n) (linear) search. - ///
- /// - public bool EnableTypeDefFindCache { - get => TypeDefFinder.IsCacheEnabled; - set => TypeDefFinder.IsCacheEnabled = value; - } - - /// - /// true if this is the manifest (main) module - /// - public bool IsManifestModule { - get { - var asm = assembly; - return asm is not null && asm.ManifestModule == this; - } - } - - /// - /// Gets the global (aka. <Module>) type or null if there are no types - /// - public TypeDef GlobalType => Types.Count == 0 ? null : Types[0]; - - /// - /// 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 - /// - public Win32Resources Win32Resources { - get { - if (!win32Resources_isInitialized) - InitializeWin32Resources(); - return win32Resources; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - win32Resources = value; - win32Resources_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected Win32Resources win32Resources; - /// - protected bool win32Resources_isInitialized; - - void InitializeWin32Resources() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (win32Resources_isInitialized) - return; - win32Resources = GetWin32Resources_NoLock(); - win32Resources_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - 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 => pdbState; - - /// - /// Module kind - /// - public ModuleKind Kind { get; set; } - - /// - /// Gets/sets the characteristics (from PE file header) - /// - public Characteristics Characteristics { get; set; } - - /// - /// Gets/sets the DLL characteristics (from PE optional header) - /// - public DllCharacteristics DllCharacteristics { get; set; } - - /// - /// Gets/sets the runtime version which is stored in the metadata header. - /// See . - /// - /// Not thread safe - public string RuntimeVersion { - get => runtimeVersion; - set { - if (runtimeVersion != value) { - runtimeVersion = value; - cachedWinMDStatus = null; - runtimeVersionWinMD = null; - winMDVersion = null; - } - } - } - string runtimeVersion; - - /// - /// Gets the WinMD status - /// - /// Not thread safe - public WinMDStatus WinMDStatus { - get { - var cval = cachedWinMDStatus; - if (cval is not null) - return cval.Value; - cachedWinMDStatus = cval = CalculateWinMDStatus(RuntimeVersion); - return cval.Value; - } - } - WinMDStatus? cachedWinMDStatus; - - /// - /// true if this is a WinMD file - /// - public bool IsWinMD => WinMDStatus != WinMDStatus.None; - - /// - /// true if this is a managed WinMD file - /// - public bool IsManagedWinMD => WinMDStatus == WinMDStatus.Managed; - - /// - /// true if this is a pure (non-managed) WinMD file - /// - public bool IsPureWinMD => WinMDStatus == WinMDStatus.Pure; - - /// - /// Gets the CLR runtime version of the managed WinMD file or null if none. This is - /// similar to for normal non-WinMD files. - /// - /// Not thread safe - public string RuntimeVersionWinMD { - get { - var rtver = runtimeVersionWinMD; - if (rtver is not null) - return rtver; - runtimeVersionWinMD = rtver = CalculateRuntimeVersionWinMD(RuntimeVersion); - return rtver; - } - } - string runtimeVersionWinMD; - - /// - /// Gets the WinMD version or null if none - /// - /// Not thread safe - public string WinMDVersion { - get { - var ver = winMDVersion; - if (ver is not null) - return ver; - winMDVersion = ver = CalculateWinMDVersion(RuntimeVersion); - return ver; - } - } - string winMDVersion; - - static WinMDStatus CalculateWinMDStatus(string version) { - if (version is null) - return WinMDStatus.None; - if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) - return WinMDStatus.None; - - return version.IndexOf(';') < 0 ? WinMDStatus.Pure : WinMDStatus.Managed; - } - - 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 is null) - return null; - if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) - return null; - int index = version.IndexOf(';'); - if (index < 0) - return null; - var s = version.Substring(index + 1); - if (s.StartsWith("CLR", StringComparison.OrdinalIgnoreCase)) - s = s.Substring(3); - s = s.TrimStart(' '); - - return s; - } - - static string CalculateWinMDVersion(string version) { - if (version is null) - return null; - if (!version.StartsWith("WindowsRuntime ", StringComparison.Ordinal)) - return null; - int index = version.IndexOf(';'); - if (index < 0) - return version; - return version.Substring(0, index); - } - - /// - /// true if is the CLR v1.0 string (only the major - /// and minor version numbers are checked) - /// - public bool IsClr10 { - get { - var ver = RuntimeVersion ?? string.Empty; - return ver.StartsWith(MDHeaderRuntimeVersion.MS_CLR_10_PREFIX) || - ver.StartsWith(MDHeaderRuntimeVersion.MS_CLR_10_PREFIX_X86RETAIL) || - ver == MDHeaderRuntimeVersion.MS_CLR_10_RETAIL || - ver == MDHeaderRuntimeVersion.MS_CLR_10_COMPLUS; - } - } - - /// - /// true if is the CLR v1.0 string - /// - 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 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_11_PREFIX); - - /// - /// true if is the CLR v1.1 string - /// - 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 => IsClr10 || IsClr11; - - /// - /// true if is the CLR v1.0 or v1.1 string - /// - 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 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_20_PREFIX); - - /// - /// true if is the CLR v2.0 string - /// - 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 => (RuntimeVersion ?? string.Empty).StartsWith(MDHeaderRuntimeVersion.MS_CLR_40_PREFIX); - - /// - /// true if is the CLR v4.0 string - /// - public bool IsClr40Exactly => RuntimeVersion == MDHeaderRuntimeVersion.MS_CLR_40; - - /// - /// true if is the ECMA 2002 string - /// - public bool IsEcma2002 => RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2002; - - /// - /// true if is the ECMA 2005 string - /// - public bool IsEcma2005 => RuntimeVersion == MDHeaderRuntimeVersion.ECMA_2005; - - /// - /// Gets/sets the (from PE header) - /// - public Machine Machine { get; set; } - - /// - /// true if is , , ... - /// - public bool IsI386 => Machine.IsI386(); - - /// - /// true if is - /// - public bool IsIA64 => Machine == Machine.IA64; - - /// - /// true if is , , ... - /// - public bool IsAMD64 => Machine.IsAMD64(); - - /// - /// true if is , , ... - /// - public bool IsARM => Machine.IsARMNT(); - - /// - /// true if is , , ... - /// - public bool IsARM64 => Machine.IsARM64(); - - /// - /// true if is s390x, , ... - /// - public bool IsS390x => Machine.IsS390x(); - - /// - /// Gets/sets the (from .NET header) - /// - public ComImageFlags Cor20HeaderFlags { - get => (ComImageFlags)cor20HeaderFlags; - set => cor20HeaderFlags = (int)value; - } - /// - protected int 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 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). - /// - public uint? Cor20HeaderRuntimeVersion { get; set; } - - /// - /// 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 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 Framework 1.x, else 2.0). - /// - public ushort? TablesHeaderVersion { get; set; } - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyComImageFlags(bool set, ComImageFlags flags) { -#if THREAD_SAFE - int origVal, newVal; - do { - origVal = cor20HeaderFlags; - if (set) - newVal = origVal | (int)flags; - else - newVal = origVal & ~(int)flags; - } while (Interlocked.CompareExchange(ref cor20HeaderFlags, newVal, origVal) != origVal); -#else - if (set) - cor20HeaderFlags |= (int)flags; - else - cor20HeaderFlags &= ~(int)flags; -#endif - } - - /// - /// Gets/sets the bit - /// - public bool IsILOnly { - get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.ILOnly) != 0; - set => ModifyComImageFlags(value, ComImageFlags.ILOnly); - } - - /// - /// Gets/sets the bit - /// - public bool Is32BitRequired { - get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.Bit32Required) != 0; - set => ModifyComImageFlags(value, ComImageFlags.Bit32Required); - } - - /// - /// Gets/sets the bit - /// - public bool IsStrongNameSigned { - get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.StrongNameSigned) != 0; - set => ModifyComImageFlags(value, ComImageFlags.StrongNameSigned); - } - - /// - /// Gets/sets the bit - /// - public bool HasNativeEntryPoint { - get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.NativeEntryPoint) != 0; - set => ModifyComImageFlags(value, ComImageFlags.NativeEntryPoint); - } - - /// - /// Gets/sets the bit - /// - public bool Is32BitPreferred { - get => ((ComImageFlags)cor20HeaderFlags & ComImageFlags.Bit32Preferred) != 0; - set => ModifyComImageFlags(value, ComImageFlags.Bit32Preferred); - } - - /// - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose method - /// - /// true if called by - protected virtual void Dispose(bool disposing) { - if (!disposing) - return; - var tdf = typeDefFinder; - if (tdf is not null) { - tdf.Dispose(); - typeDefFinder = null; - } - pdbState?.Dispose(); - pdbState = null; - } - - /// - /// Gets all the types (including nested types) present in this module - /// - public IEnumerable GetTypes() => AllTypesHelper.Types(Types); - - /// - /// Adds as a non-nested type. If it's already nested, its - /// will be set to null. - /// - /// The to insert - public void AddAsNonNestedType(TypeDef typeDef) { - if (typeDef is null) - return; - typeDef.DeclaringType = null; - Types.Add(typeDef); - } - - /// - /// Updates the rid to the next free rid available. It's only updated if - /// the original rid is 0. - /// - /// IMDTokenProvider - /// The row that should be updated - /// Returns the input - public T UpdateRowId(T tableRow) where T : IMDTokenProvider { - if (tableRow != null && tableRow.Rid == 0) - tableRow.Rid = GetNextFreeRid(tableRow.MDToken.Table); - return tableRow; - } - - /// - /// Updates the rid to the next free rid available. - /// - /// IMDTokenProvider - /// The row that should be updated - /// Returns the input - public T ForceUpdateRowId(T tableRow) where T : IMDTokenProvider { - if (tableRow != null) - tableRow.Rid = GetNextFreeRid(tableRow.MDToken.Table); - return tableRow; - } - - uint GetNextFreeRid(Table table) { - var lastUsedRids = this.lastUsedRids; - if ((uint)table >= lastUsedRids.Length) - return 0; - return (uint)Interlocked.Increment(ref lastUsedRids[(int)table]) & 0x00FFFFFF; - } - - /// - /// Imports a as a - /// - /// The type - /// The imported type or null if is invalid - 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) => new Importer(this).ImportAsTypeSig(type); - - /// - /// Imports a as a - /// - /// The field - /// The imported field or null if is invalid - /// or if we failed to import the field - public MemberRef Import(FieldInfo fieldInfo) => (MemberRef)new Importer(this).Import(fieldInfo); - - /// - /// Imports a as a . This will be either - /// a or a . - /// - /// The method - /// The imported method or null if is invalid - /// or if we failed to import the method - public IMethod Import(MethodBase methodBase) => new Importer(this).Import(methodBase); - - /// - /// Imports a - /// - /// The type - /// The imported type or null - 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) => (TypeRef)new Importer(this).Import(type); - - /// - /// Imports a - /// - /// The type - /// The imported type or null - 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) => new Importer(this).Import(type); - - /// - /// Imports a - /// - /// The type - /// The imported type or null - 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) => (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) => (MemberRef)new Importer(this).Import(field); - - /// - /// Imports a - /// - /// The method - /// The imported method or null if is invalid - 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) => (MemberRef)new Importer(this).Import(method); - - /// - /// Imports a - /// - /// The method - /// The imported method or null if is invalid - 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) => 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); - - /// - /// Writes the module to a file on disk. If the file exists, it will be overwritten. - /// - /// Filename - /// Writer options - public void Write(string filename, ModuleWriterOptions options) { - var writer = new ModuleWriter(this, options ?? new ModuleWriterOptions(this)); - writer.Write(filename); - } - - /// - /// Writes the module to a stream. - /// - /// Destination stream - public void Write(Stream dest) => Write(dest, null); - - /// - /// Writes the module to a stream. - /// - /// Destination stream - /// Writer options - public void Write(Stream dest, ModuleWriterOptions options) { - var writer = new ModuleWriter(this, options ?? new ModuleWriterOptions(this)); - writer.Write(dest); - } - - /// - /// Resets the cache which can be enabled by setting - /// 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(); - - /// - /// Finds a - /// - /// Type - /// Name - /// Language ID - /// The or null if none found - 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)); - - /// - /// Sets a - /// - /// New - 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 not null) - throw new InvalidOperationException("PDB file has already been initialized"); - } - - uint GetCor20RuntimeVersion() { - var rtVer = Cor20HeaderRuntimeVersion; - if (rtVer is not null) - return rtVer.Value; - return IsClr1x ? 0x00020000U : 0x00020005; - } - - /// - /// Returns the size of a pointer. Assumes it's 32-bit if pointer size is unknown or - /// if it can be 32-bit or 64-bit. - /// - /// Size of a pointer (4 or 8) - public int GetPointerSize() => GetPointerSize(4); - - /// - /// Returns the size of a pointer - /// - /// 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) => 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.Is64Bit()) - return 8; - if (!machine.IsI386()) - return 4; - - // Machine is I386 so it's either x86 or platform neutral - - // If the runtime version is < 2.5, then it's always loaded as a 32-bit process. - if (GetCor20RuntimeVersion() < 0x00020005) - return 4; - - // If it's a 32-bit PE header, and ILOnly is cleared, it's always loaded as a - // 32-bit process. - var flags = (ComImageFlags)cor20HeaderFlags; - if ((flags & ComImageFlags.ILOnly) == 0) - return 4; - - // 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 - break; - - case ComImageFlags.Bit32Preferred: - // Illegal - break; - - case ComImageFlags.Bit32Required: - // x86 image (32-bit process) - return 4; - - case ComImageFlags.Bit32Required | ComImageFlags.Bit32Preferred: - // Platform neutral but prefers to be 32-bit - return prefer32bitPointerSize; - } - - return defaultPointerSize; - } - - /// - void IListListener.OnLazyAdd(int index, ref TypeDef value) { -#if DEBUG - 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 not null) - throw new InvalidOperationException("Nested type is already owned by another type. Set DeclaringType to null first."); - 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; - } - - /// - void IListListener.OnRemove(int index, TypeDef value) => value.Module2 = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var type in types.GetEnumerable_NoLock()) - type.Module2 = null; - } - - /// - /// Finds a . For speed, enable - /// if possible (read the documentation first). - /// - /// Full name of the type (no assembly information) - /// true if it's a reflection name, and nested - /// 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) => TypeDefFinder.Find(fullName, isReflectionName); - - /// - /// Finds a . Its scope (i.e., module or assembly) is ignored when - /// looking up the type. For speed, enable if possible - /// (read the documentation first). - /// - /// The type ref - /// An existing or null if it wasn't found. - public TypeDef Find(TypeRef typeRef) => TypeDefFinder.Find(typeRef); - - /// - /// Finds a - /// - /// The type - /// A or null if it wasn't found - public TypeDef Find(ITypeDefOrRef typeRef) { - if (typeRef is TypeDef td) - return td.Module == this ? td : null; - - if (typeRef is TypeRef tr) - return Find(tr); - - var ts = typeRef as TypeSpec; - if (ts is null) - return null; - var sig = ts.TypeSig as TypeDefOrRefSig; - if (sig is null) - return null; - - td = sig.TypeDef; - if (td is not null) - return td.Module == this ? td : null; - - tr = sig.TypeRef; - if (tr is not null) - return Find(tr); - - return null; - } - - /// - /// Creates a new instance. There should normally only be one - /// instance shared by all s. - /// - /// A new instance - public static ModuleContext CreateModuleContext() { - var ctx = new ModuleContext(); - var asmRes = new AssemblyResolver(ctx); - var res = new Resolver(asmRes); - ctx.AssemblyResolver = asmRes; - ctx.Resolver = res; - asmRes.DefaultModuleContext = ctx; - 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. - /// - /// Cancellation token or null - public virtual void LoadEverything(ICancellationToken cancellationToken = null) => ModuleLoader.LoadAll(this, cancellationToken); - - /// - public override string ToString() => FullName; - - /// - /// Resolves a token - /// - /// The metadata token - /// A or null if is invalid - public IMDTokenProvider ResolveToken(MDToken mdToken) => ResolveToken(mdToken.Raw, new GenericParamContext()); - - /// - /// Resolves a token - /// - /// The metadata token - /// Generic parameter context - /// A or null if is invalid - 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) => 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) => ResolveToken((uint)token, gpContext); - - /// - /// Resolves a token - /// - /// The metadata token - /// A or null if is invalid - public IMDTokenProvider ResolveToken(uint token) => ResolveToken(token, new GenericParamContext()); - - /// - /// Resolves a token - /// - /// The metadata token - /// Generic parameter context - /// A or null if is invalid - public virtual IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext) => null; - - /// - /// Gets all s - /// - public IEnumerable GetAssemblyRefs() { - for (uint rid = 1; ; rid++) { - var asmRef = ResolveToken(new MDToken(Table.AssemblyRef, rid).Raw) as AssemblyRef; - if (asmRef is null) - break; - yield return asmRef; - } - } - - /// - /// Gets all s - /// - public IEnumerable GetModuleRefs() { - for (uint rid = 1; ; rid++) { - var modRef = ResolveToken(new MDToken(Table.ModuleRef, rid).Raw) as ModuleRef; - if (modRef is null) - break; - yield return modRef; - } - } - - /// - /// Gets all s. s with generic parameters - /// aren't cached and a new copy is always returned. - /// - public IEnumerable GetMemberRefs() => GetMemberRefs(new GenericParamContext()); - - /// - /// Gets all s. s with generic parameters - /// aren't cached and a new copy is always returned. - /// - /// Generic parameter context - public IEnumerable GetMemberRefs(GenericParamContext gpContext) { - for (uint rid = 1; ; rid++) { - var mr = ResolveToken(new MDToken(Table.MemberRef, rid).Raw, gpContext) as MemberRef; - if (mr is null) - break; - yield return mr; - } - } - - /// - /// Gets all s - /// - public IEnumerable GetTypeRefs() { - for (uint rid = 1; ; rid++) { - var mr = ResolveToken(new MDToken(Table.TypeRef, rid).Raw) as TypeRef; - if (mr is null) - break; - yield return mr; - } - } - - /// - /// Finds an assembly reference by name. If there's more than one, pick the one with - /// the greatest version number. - /// - /// Simple name of assembly (eg. "mscorlib") - /// The found or null if there's no such - /// assembly reference. - public AssemblyRef GetAssemblyRef(UTF8String simpleName) { - AssemblyRef found = null; - foreach (var asmRef in GetAssemblyRefs()) { - if (asmRef.Name != simpleName) - continue; - if (IsGreaterAssemblyRefVersion(found, asmRef)) - found = asmRef; - } - return found; - } - - /// - /// Compare asm refs' version - /// - /// First asm ref - /// New asm ref - /// - protected static bool IsGreaterAssemblyRefVersion(AssemblyRef found, AssemblyRef newOne) { - if (found is null) - return true; - var foundVer = found.Version; - var newVer = newOne.Version; - return foundVer is null || (newVer is not null && newVer >= foundVer); - } - - ITypeDefOrRef ISignatureReaderHelper.ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) - return null; - return ResolveToken(token) as ITypeDefOrRef; - } - - TypeSig ISignatureReaderHelper.ConvertRTInternalAddress(IntPtr address) => null; - } - - /// - /// A Module row created by the user and not present in the original .NET file - /// - public class ModuleDefUser : ModuleDef { - /// - /// Default constructor - /// - public ModuleDefUser() - : this(null, null) { - } - - /// - /// Constructor - /// - /// is initialized to a random - /// Module nam - public ModuleDefUser(UTF8String name) - : this(name, Guid.NewGuid()) { - } - - /// - /// Constructor - /// - /// Module name - /// Module version ID - public ModuleDefUser(UTF8String name, Guid? mvid) - : this(name, mvid, null) { - } - - /// - /// Constructor - /// - /// Module name - /// Module version ID - /// Corlib assembly ref or null - public ModuleDefUser(UTF8String name, Guid? mvid, AssemblyRef corLibAssemblyRef) { - Kind = ModuleKind.Windows; - Characteristics = DefaultCharacteristics; - DllCharacteristics = DefaultDllCharacteristics; - RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; - Machine = Machine.I386; - cor20HeaderFlags = (int)ComImageFlags.ILOnly; - 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(); - corLibTypes = new CorLibTypes(this, corLibAssemblyRef); - types = new LazyList(this); - this.name = name; - this.mvid = mvid; - types.Add(CreateModuleType()); - UpdateRowId(this); - } - - TypeDef CreateModuleType() { - var type = UpdateRowId(new TypeDefUser(UTF8String.Empty, "", null)); - type.Attributes = TypeAttributes.NotPublic | TypeAttributes.AutoLayout | TypeAttributes.Class | TypeAttributes.AnsiClass; - return type; - } - } - - /// - /// Created from a row in the Module table - /// - public class ModuleDefMD2 : ModuleDef, 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.Module, 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); - } - - /// - protected override RVA GetNativeEntryPoint_NoLock() => readerModule.GetNativeEntryPoint(); - - /// - protected override IManagedEntryPoint GetManagedEntryPoint_NoLock() => readerModule.GetManagedEntryPoint(); - - /// - /// Constructor - /// - /// The module which contains this Module row - /// Row ID - /// If is null - /// If is invalid - internal ModuleDefMD2(ModuleDefMD readerModule, uint rid) { - if (rid == 1 && readerModule is null) - readerModule = (ModuleDefMD)this; -#if DEBUG - 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"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - if (rid != 1) { - Kind = ModuleKind.Windows; - Characteristics = DefaultCharacteristics; - DllCharacteristics = DefaultDllCharacteristics; - RuntimeVersion = MDHeaderRuntimeVersion.MS_CLR_20; - Machine = Machine.I386; - cor20HeaderFlags = (int)ComImageFlags.ILOnly; - 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(); - } - } - - /// - /// Initialize fields from the raw Module row - /// - protected void InitializeFromRawRow() { - bool b = readerModule.TablesStream.TryReadModuleRow(origRid, out var row); - Debug.Assert(b); - generation = row.Generation; - mvid = readerModule.GuidStream.Read(row.Mvid); - encId = readerModule.GuidStream.Read(row.EncId); - encBaseId = readerModule.GuidStream.Read(row.EncBaseId); - name = readerModule.StringsStream.ReadNoNull(row.Name); - if (origRid == 1) - assembly = readerModule.ResolveAssembly(origRid); - } - } -} diff --git a/Plugins/dnlib/DotNet/ModuleDefMD.cs b/Plugins/dnlib/DotNet/ModuleDefMD.cs deleted file mode 100644 index f37e84f..0000000 --- a/Plugins/dnlib/DotNet/ModuleDefMD.cs +++ /dev/null @@ -1,1867 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.ExceptionServices; -using System.Runtime.InteropServices; -using System.Security; -using System.Threading; -using dnlib.PE; -using dnlib.Utils; -using dnlib.IO; -using dnlib.DotNet.MD; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Pdb; -using dnlib.W32Resources; - -using DNW = dnlib.DotNet.Writer; -using dnlib.DotNet.Pdb.Symbols; -using System.Runtime.CompilerServices; - -namespace dnlib.DotNet { - /// - /// Created from a row in the Module table - /// - public sealed class ModuleDefMD : ModuleDefMD2, IInstructionOperandResolver { - /// The file that contains all .NET metadata - MetadataBase metadata; - IMethodDecrypter methodDecrypter; - IStringDecrypter stringDecrypter; - - StrongBox moduleRidList; - - SimpleLazyList listModuleDefMD; - SimpleLazyList listTypeRefMD; - SimpleLazyList listTypeDefMD; - SimpleLazyList listFieldDefMD; - SimpleLazyList listMethodDefMD; - SimpleLazyList listParamDefMD; - SimpleLazyList2 listInterfaceImplMD; - SimpleLazyList2 listMemberRefMD; - SimpleLazyList listConstantMD; - SimpleLazyList listDeclSecurityMD; - SimpleLazyList listClassLayoutMD; - SimpleLazyList2 listStandAloneSigMD; - SimpleLazyList listEventDefMD; - SimpleLazyList listPropertyDefMD; - SimpleLazyList listModuleRefMD; - SimpleLazyList2 listTypeSpecMD; - SimpleLazyList listImplMapMD; - SimpleLazyList listAssemblyDefMD; - SimpleLazyList listAssemblyRefMD; - SimpleLazyList listFileDefMD; - SimpleLazyList listExportedTypeMD; - SimpleLazyList listManifestResourceMD; - SimpleLazyList listGenericParamMD; - SimpleLazyList2 listMethodSpecMD; - SimpleLazyList2 listGenericParamConstraintMD; - - /// - /// Gets/sets the method decrypter - /// - public IMethodDecrypter MethodDecrypter { - get => methodDecrypter; - set => methodDecrypter = value; - } - - /// - /// Gets/sets the string decrypter - /// - public IStringDecrypter StringDecrypter { - get => stringDecrypter; - set => stringDecrypter = value; - } - - /// - /// Returns the .NET metadata interface - /// - public Metadata Metadata => metadata; - - /// - /// Returns the #~ or #- tables stream - /// - public TablesStream TablesStream => metadata.TablesStream; - - /// - /// Returns the #Strings stream - /// - public StringsStream StringsStream => metadata.StringsStream; - - /// - /// Returns the #Blob stream - /// - public BlobStream BlobStream => metadata.BlobStream; - - /// - /// Returns the #GUID stream - /// - public GuidStream GuidStream => metadata.GuidStream; - - /// - /// Returns the #US stream - /// - public USStream USStream => metadata.USStream; - - /// - protected override void InitializeTypes() { - var list = Metadata.GetNonNestedClassRidList(); - var tmp = new LazyList(list.Count, this, list, (list2, index) => ResolveTypeDef(list2[index])); - Interlocked.CompareExchange(ref types, tmp, null); - } - - /// - protected override void InitializeExportedTypes() { - var list = Metadata.GetExportedTypeRidList(); - var tmp = new LazyList(list.Count, list, (list2, i) => ResolveExportedType(list2[i])); - Interlocked.CompareExchange(ref exportedTypes, tmp, null); - } - - /// - protected override void InitializeResources() { - var table = TablesStream.ManifestResourceTable; - var tmp = new ResourceCollection((int)table.Rows, null, (ctx, i) => CreateResource((uint)i + 1)); - Interlocked.CompareExchange(ref resources, tmp, null); - } - - /// - protected override Win32Resources GetWin32Resources_NoLock() => metadata.PEImage.Win32Resources; - - /// - protected override VTableFixups GetVTableFixups_NoLock() { - var vtableFixupsInfo = metadata.ImageCor20Header.VTableFixups; - if (vtableFixupsInfo.VirtualAddress == 0 || vtableFixupsInfo.Size == 0) - return null; - return new VTableFixups(this); - } - - /// - /// Creates a instance from a file - /// - /// File name of an existing .NET module/assembly - /// Module context or null - /// A new instance - public static ModuleDefMD Load(string fileName, ModuleContext context) => Load(fileName, new ModuleCreationOptions(context)); - - /// - /// Creates a instance from a file - /// - /// 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?.Runtime ?? CLRRuntimeReaderKind.CLR), options); - - /// - /// Creates a instance from a byte[] - /// - /// Contents of a .NET module/assembly - /// Module context or null - /// A new instance - public static ModuleDefMD Load(byte[] data, ModuleContext context) => Load(data, new ModuleCreationOptions(context)); - - /// - /// Creates a instance from a byte[] - /// - /// 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?.Runtime ?? CLRRuntimeReaderKind.CLR), options); - - /// - /// Creates a instance from a reflection module - /// - /// An existing reflection module - /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod) => Load(mod, (ModuleCreationOptions)null, GetImageLayout(mod)); - - /// - /// Creates a instance from a reflection module - /// - /// An existing reflection module - /// Module context or null - /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod, ModuleContext context) => Load(mod, new ModuleCreationOptions(context), GetImageLayout(mod)); - - /// - /// Creates a instance from a reflection module - /// - /// An existing reflection module - /// Module creation options or null - /// A new instance - 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; - if (fqn.Length > 0 && fqn[0] == '<' && fqn[fqn.Length - 1] == '>') - return ImageLayout.File; - return ImageLayout.Memory; - } - - /// - /// Creates a instance from a reflection module - /// - /// An existing reflection module - /// 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) => Load(mod, new ModuleCreationOptions(context), imageLayout); - - static IntPtr GetModuleHandle(System.Reflection.Module mod) { -#if NETSTANDARD - var GetHINSTANCE = typeof(Marshal).GetMethod("GetHINSTANCE", new[] { typeof(System.Reflection.Module) }); - if (GetHINSTANCE is null) - return IntPtr.Zero; - - return (IntPtr)GetHINSTANCE.Invoke(null, new[] { mod }); -#else - return Marshal.GetHINSTANCE(mod); -#endif - } - - /// - /// Creates a instance from a reflection module - /// - /// An existing reflection module - /// Module creation options or null - /// Image layout of the module in memory - /// A new instance - public static ModuleDefMD Load(System.Reflection.Module mod, ModuleCreationOptions options, ImageLayout imageLayout) { - var addr = GetModuleHandle(mod); - 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(location, options); - } - - /// - /// Creates a instance from a memory location - /// - /// Address of a .NET module/assembly - /// A new instance - public static ModuleDefMD Load(IntPtr addr) => Load(MetadataFactory.Load(addr, CLRRuntimeReaderKind.CLR), (ModuleCreationOptions)null); - - /// - /// Creates a instance from a memory location - /// - /// 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, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); - - /// - /// Creates a instance from a memory location - /// - /// 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?.Runtime ?? CLRRuntimeReaderKind.CLR), options); - - /// - /// Creates a instance - /// - /// PE image - /// A new instance - public static ModuleDefMD Load(IPEImage peImage) => Load(MetadataFactory.Load(peImage, CLRRuntimeReaderKind.CLR), (ModuleCreationOptions)null); - - /// - /// Creates a instance - /// - /// PE image - /// Module context or null - /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleContext context) => Load(MetadataFactory.Load(peImage, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); - - /// - /// Creates a instance - /// - /// PE image - /// Module creation options or null - /// A new instance - public static ModuleDefMD Load(IPEImage peImage, ModuleCreationOptions options) => Load(MetadataFactory.Load(peImage, options?.Runtime ?? CLRRuntimeReaderKind.CLR), options); - - /// - /// Creates a instance from a memory location - /// - /// Address of a .NET module/assembly - /// 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, CLRRuntimeReaderKind.CLR), new ModuleCreationOptions(context)); - - /// - /// Creates a instance from a memory location - /// - /// Address of a .NET module/assembly - /// 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?.Runtime ?? CLRRuntimeReaderKind.CLR), options); - - /// - /// Creates a 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 (owned by caller) - /// A new instance - /// If is null - public static ModuleDefMD Load(Stream stream) => Load(stream, (ModuleCreationOptions)null); - - /// - /// Creates a 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 (owned by caller) - /// Module context or null - /// A new instance - /// If is null - public static ModuleDefMD Load(Stream stream, ModuleContext context) => Load(stream, new ModuleCreationOptions(context)); - - /// - /// Creates a 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 (owned by caller) - /// Module creation options or null - /// A new instance - /// If is null - public static ModuleDefMD Load(Stream stream, ModuleCreationOptions options) { - if (stream is null) - throw new ArgumentNullException(nameof(stream)); - if (stream.Length > int.MaxValue) - throw new ArgumentException("Stream is too big"); - var data = new byte[(int)stream.Length]; - stream.Position = 0; - if (stream.Read(data, 0, data.Length) != data.Length) - throw new IOException("Could not read all bytes from the stream"); - return Load(data, options); - } - - /// - /// Creates a instance from a - /// - /// The metadata - /// Module creation options or null - /// A new instance that now owns - internal static ModuleDefMD Load(MetadataBase metadata, ModuleCreationOptions options) => new ModuleDefMD(metadata, options); - - /// - /// Constructor - /// - /// The metadata - /// Module creation options or null - /// If is null - ModuleDefMD(MetadataBase metadata, ModuleCreationOptions options) - : base(null, 1) { -#if DEBUG - if (metadata is null) - throw new ArgumentNullException(nameof(metadata)); -#endif - if (options is null) - options = ModuleCreationOptions.Default; - this.metadata = metadata; - context = options.Context; - Initialize(); - InitializeFromRawRow(); - location = metadata.PEImage.Filename ?? string.Empty; - - 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); - } - - void InitializePdb(ModuleCreationOptions options) { - if (options is null) - return; - LoadPdb(CreateSymbolReader(options)); - } - - SymbolReader CreateSymbolReader(ModuleCreationOptions options) { - 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 not null) - return symReader; - } - - if (options.PdbFileOrData is byte[] pdbData) - return SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbData); - - if (options.PdbFileOrData is DataReaderFactory pdbStream) - return SymbolReaderFactory.Create(options.PdbOptions, metadata, pdbStream); - } - - if (options.TryToLoadPdbFromDisk) - return SymbolReaderFactory.CreateFromAssemblyFile(options.PdbOptions, metadata, location ?? string.Empty); - - return null; - } - - /// - /// Loads symbols using - /// - /// PDB symbol reader - public void LoadPdb(SymbolReader symbolReader) { - if (symbolReader is null) - return; - 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 not null) - throw new InvalidOperationException("PDB file has already been initialized"); - } - - /// - /// Loads symbols from a PDB file - /// - /// PDB file name - public void LoadPdb(string pdbFileName) => - LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbFileName); - - /// - /// Loads symbols from a PDB file - /// - /// PDB reader options - /// PDB file name - public void LoadPdb(PdbReaderOptions options, string pdbFileName) => - LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbFileName)); - - /// - /// Loads symbols from a byte array - /// - /// PDB data - public void LoadPdb(byte[] pdbData) => - LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbData); - - /// - /// Loads symbols from a byte array - /// - /// PDB reader options - /// PDB data - public void LoadPdb(PdbReaderOptions options, byte[] pdbData) => - LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbData)); - - /// - /// Loads symbols from a stream - /// - /// PDB file stream which is now owned by us - public void LoadPdb(DataReaderFactory pdbStream) => - LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions, pdbStream); - - /// - /// Loads symbols from a stream - /// - /// PDB reader options - /// PDB file stream which is now owned by us - public void LoadPdb(PdbReaderOptions options, DataReaderFactory pdbStream) => - LoadPdb(SymbolReaderFactory.Create(options, metadata, pdbStream)); - - /// - /// Loads symbols if a PDB file is available - /// - public void LoadPdb() => - LoadPdb(ModuleCreationOptions.DefaultPdbReaderOptions); - - /// - /// Loads symbols if a PDB file is available - /// - /// PDB reader options - 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; - if (ps is null) - return; - ps.InitializeCustomDebugInfos(token, gpContext, result); - } - - ModuleKind GetKind() { - if (TablesStream.AssemblyTable.Rows < 1) - return ModuleKind.NetModule; - - var peImage = Metadata.PEImage; - if ((peImage.ImageNTHeaders.FileHeader.Characteristics & Characteristics.Dll) != 0) - return ModuleKind.Dll; - - return peImage.ImageNTHeaders.OptionalHeader.Subsystem switch { - Subsystem.WindowsCui => ModuleKind.Console, - _ => ModuleKind.Windows, - }; - } - - void Initialize() { - var ts = metadata.TablesStream; - - listModuleDefMD = new SimpleLazyList(ts.ModuleTable.Rows, rid2 => rid2 == 1 ? this : new ModuleDefMD2(this, rid2)); - listTypeRefMD = new SimpleLazyList(ts.TypeRefTable.Rows, rid2 => new TypeRefMD(this, rid2)); - listTypeDefMD = new SimpleLazyList(ts.TypeDefTable.Rows, rid2 => new TypeDefMD(this, rid2)); - listFieldDefMD = new SimpleLazyList(ts.FieldTable.Rows, rid2 => new FieldDefMD(this, rid2)); - listMethodDefMD = new SimpleLazyList(ts.MethodTable.Rows, rid2 => new MethodDefMD(this, rid2)); - listParamDefMD = new SimpleLazyList(ts.ParamTable.Rows, rid2 => new ParamDefMD(this, rid2)); - listInterfaceImplMD = new SimpleLazyList2(ts.InterfaceImplTable.Rows, (rid2, gpContext) => new InterfaceImplMD(this, rid2, gpContext)); - listMemberRefMD = new SimpleLazyList2(ts.MemberRefTable.Rows, (rid2, gpContext) => new MemberRefMD(this, rid2, gpContext)); - listConstantMD = new SimpleLazyList(ts.ConstantTable.Rows, rid2 => new ConstantMD(this, rid2)); - listDeclSecurityMD = new SimpleLazyList(ts.DeclSecurityTable.Rows, rid2 => new DeclSecurityMD(this, rid2)); - listClassLayoutMD = new SimpleLazyList(ts.ClassLayoutTable.Rows, rid2 => new ClassLayoutMD(this, rid2)); - listStandAloneSigMD = new SimpleLazyList2(ts.StandAloneSigTable.Rows, (rid2, gpContext) => new StandAloneSigMD(this, rid2, gpContext)); - listEventDefMD = new SimpleLazyList(ts.EventTable.Rows, rid2 => new EventDefMD(this, rid2)); - listPropertyDefMD = new SimpleLazyList(ts.PropertyTable.Rows, rid2 => new PropertyDefMD(this, rid2)); - listModuleRefMD = new SimpleLazyList(ts.ModuleRefTable.Rows, rid2 => new ModuleRefMD(this, rid2)); - listTypeSpecMD = new SimpleLazyList2(ts.TypeSpecTable.Rows, (rid2, gpContext) => new TypeSpecMD(this, rid2, gpContext)); - listImplMapMD = new SimpleLazyList(ts.ImplMapTable.Rows, rid2 => new ImplMapMD(this, rid2)); - listAssemblyDefMD = new SimpleLazyList(ts.AssemblyTable.Rows, rid2 => new AssemblyDefMD(this, rid2)); - listFileDefMD = new SimpleLazyList(ts.FileTable.Rows, rid2 => new FileDefMD(this, rid2)); - listAssemblyRefMD = new SimpleLazyList(ts.AssemblyRefTable.Rows, rid2 => new AssemblyRefMD(this, rid2)); - listExportedTypeMD = new SimpleLazyList(ts.ExportedTypeTable.Rows, rid2 => new ExportedTypeMD(this, rid2)); - listManifestResourceMD = new SimpleLazyList(ts.ManifestResourceTable.Rows, rid2 => new ManifestResourceMD(this, rid2)); - listGenericParamMD = new SimpleLazyList(ts.GenericParamTable.Rows, rid2 => new GenericParamMD(this, rid2)); - listMethodSpecMD = new SimpleLazyList2(ts.MethodSpecTable.Rows, (rid2, gpContext) => new MethodSpecMD(this, rid2, gpContext)); - listGenericParamConstraintMD = new SimpleLazyList2(ts.GenericParamConstraintTable.Rows, (rid2, gpContext) => new GenericParamConstraintMD(this, rid2, gpContext)); - - for (int i = 0; i < 64; i++) { - var tbl = TablesStream.Get((Table)i); - lastUsedRids[i] = tbl is null ? 0 : (int)tbl.Rows; - } - } - - static readonly Dictionary preferredCorLibs = new Dictionary(StringComparer.OrdinalIgnoreCase) { - // .NET Framework - { "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 100 }, - { "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 90 }, - { "mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 60 }, - { "mscorlib, Version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", 50 }, - - // Silverlight - { "mscorlib, Version=5.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", 80 }, - { "mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e", 70 }, - - // Zune - { "mscorlib, Version=3.5.0.0, Culture=neutral, PublicKeyToken=e92a8b81eba7ceb7", 60 }, - - // Compact Framework - { "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 - /// - /// An existing instance or null if it wasn't found - AssemblyRef FindCorLibAssemblyRef() { - var numAsmRefs = TablesStream.AssemblyRefTable.Rows; - AssemblyRef corLibAsmRef = null; - - int currentPriority = int.MinValue; - for (uint i = 1; i <= numAsmRefs; i++) { - var asmRef = ResolveAssemblyRef(i); - if (!preferredCorLibs.TryGetValue(asmRef.FullName, out int priority)) - continue; - if (priority > currentPriority) { - currentPriority = priority; - corLibAsmRef = asmRef; - } - } - if (corLibAsmRef is not null) - return corLibAsmRef; - - 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 not null) - return corLibAsmRef; - } - - // If we've loaded mscorlib itself, it won't have any AssemblyRefs to itself. - var asm = Assembly; - if (asm is not null && (asm.IsCorLib() || Find("System.Object", false) is not null)) { - IsCoreLibraryModule = true; - return UpdateRowId(new AssemblyRefUser(asm)); - } - - return corLibAsmRef; - } - - /// - /// Called when no corlib assembly reference was found - /// - /// - AssemblyRef CreateDefaultCorLibAssemblyRef() { - var asmRef = GetAlternativeCorLibReference(); - if (asmRef is not null) - return UpdateRowId(asmRef); - - if (IsClr40) - return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR40()); - if (IsClr20) - return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR20()); - if (IsClr11) - return UpdateRowId(AssemblyRefUser.CreateMscorlibReferenceCLR11()); - if (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 is 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) { - // Call base first since it will dispose of all the resources, which will - // eventually use metadata that we will dispose - base.Dispose(disposing); - if (disposing) { - var md = metadata; - if (md is not null) - md.Dispose(); - metadata = null; - } - } - - /// - /// Resolves a token - /// - /// The metadata token - /// Generic parameter context - /// A or null if is invalid - public override IMDTokenProvider ResolveToken(uint token, GenericParamContext gpContext) { - uint rid = MDToken.ToRID(token); - 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, - }; - } - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listTypeRefMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listFieldDefMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listParamDefMD[rid - 1]; - - /// - /// Resolves an - /// - /// The row ID - /// A instance or null if is invalid - public InterfaceImpl ResolveInterfaceImpl(uint rid) => listInterfaceImplMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves an - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => listMemberRefMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves a - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => listConstantMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listClassLayoutMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - public StandAloneSig ResolveStandAloneSig(uint rid) => listStandAloneSigMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves a - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => listEventDefMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listModuleRefMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - public TypeSpec ResolveTypeSpec(uint rid) => listTypeSpecMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves a - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => listImplMapMD[rid - 1]; - - /// - /// Resolves an - /// - /// The row ID - /// A instance or null if is invalid - 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) => listAssemblyRefMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listExportedTypeMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - 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) => listGenericParamMD[rid - 1]; - - /// - /// Resolves a - /// - /// The row ID - /// A instance or null if is invalid - public MethodSpec ResolveMethodSpec(uint rid) => listMethodSpecMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves a - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => listGenericParamConstraintMD[rid - 1, new GenericParamContext()]; - - /// - /// Resolves a - /// - /// The row ID - /// Generic parameter context - /// A instance or null if is invalid - 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) => ResolveTypeDefOrRef(codedToken, new GenericParamContext()); - - /// - /// Resolves a - /// - /// A TypeDefOrRef coded token - /// Generic parameter context - /// A or null if is invalid - public ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.TypeDefOrRef.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.TypeDef => ResolveTypeDef(rid), - Table.TypeRef => ResolveTypeRef(rid), - Table.TypeSpec => ResolveTypeSpec(rid, gpContext), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A HasConstant coded token - /// A or null if is invalid - public IHasConstant ResolveHasConstant(uint codedToken) { - if (!CodedToken.HasConstant.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Field => ResolveField(rid), - Table.Param => ResolveParam(rid), - Table.Property => ResolveProperty(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A HasCustomAttribute coded token - /// A or null if is invalid - public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken) => ResolveHasCustomAttribute(codedToken, new GenericParamContext()); - - /// - /// Resolves a - /// - /// A HasCustomAttribute coded token - /// Generic parameter context - /// A or null if is invalid - public IHasCustomAttribute ResolveHasCustomAttribute(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.HasCustomAttribute.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - 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, - }; - } - - /// - /// Resolves a - /// - /// A HasFieldMarshal coded token - /// A or null if is invalid - public IHasFieldMarshal ResolveHasFieldMarshal(uint codedToken) { - if (!CodedToken.HasFieldMarshal.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Field => ResolveField(rid), - Table.Param => ResolveParam(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A HasDeclSecurity coded token - /// A or null if is invalid - public IHasDeclSecurity ResolveHasDeclSecurity(uint codedToken) { - if (!CodedToken.HasDeclSecurity.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.TypeDef => ResolveTypeDef(rid), - Table.Method => ResolveMethod(rid), - Table.Assembly => ResolveAssembly(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A MemberRefParent coded token - /// A or null if is invalid - public IMemberRefParent ResolveMemberRefParent(uint codedToken) => ResolveMemberRefParent(codedToken, new GenericParamContext()); - - /// - /// Resolves a - /// - /// A MemberRefParent coded token - /// Generic parameter context - /// A or null if is invalid - public IMemberRefParent ResolveMemberRefParent(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.MemberRefParent.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - 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, - }; - } - - /// - /// Resolves a - /// - /// A HasSemantic coded token - /// A or null if is invalid - public IHasSemantic ResolveHasSemantic(uint codedToken) { - if (!CodedToken.HasSemantic.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Event => ResolveEvent(rid), - Table.Property => ResolveProperty(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A MethodDefOrRef coded token - /// A or null if is invalid - public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken) => ResolveMethodDefOrRef(codedToken, new GenericParamContext()); - - /// - /// Resolves a - /// - /// A MethodDefOrRef coded token - /// Generic parameter context - /// A or null if is invalid - public IMethodDefOrRef ResolveMethodDefOrRef(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.MethodDefOrRef.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Method => ResolveMethod(rid), - Table.MemberRef => ResolveMemberRef(rid, gpContext), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A MemberForwarded coded token - /// A or null if is invalid - public IMemberForwarded ResolveMemberForwarded(uint codedToken) { - if (!CodedToken.MemberForwarded.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Field => ResolveField(rid), - Table.Method => ResolveMethod(rid), - _ => null, - }; - } - - /// - /// Resolves an - /// - /// An Implementation coded token - /// A or null if is invalid - public IImplementation ResolveImplementation(uint codedToken) { - if (!CodedToken.Implementation.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.File => ResolveFile(rid), - Table.AssemblyRef => ResolveAssemblyRef(rid), - Table.ExportedType => ResolveExportedType(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A CustomAttributeType coded token - /// A or null if is invalid - public ICustomAttributeType ResolveCustomAttributeType(uint codedToken) => ResolveCustomAttributeType(codedToken, new GenericParamContext()); - - /// - /// Resolves a - /// - /// A CustomAttributeType coded token - /// Generic parameter context - /// A or null if is invalid - public ICustomAttributeType ResolveCustomAttributeType(uint codedToken, GenericParamContext gpContext) { - if (!CodedToken.CustomAttributeType.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Method => ResolveMethod(rid), - Table.MemberRef => ResolveMemberRef(rid, gpContext), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A ResolutionScope coded token - /// A or null if is invalid - public IResolutionScope ResolveResolutionScope(uint codedToken) { - if (!CodedToken.ResolutionScope.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.Module => ResolveModule(rid), - Table.ModuleRef => ResolveModuleRef(rid), - Table.AssemblyRef => ResolveAssemblyRef(rid), - Table.TypeRef => ResolveTypeRef(rid), - _ => null, - }; - } - - /// - /// Resolves a - /// - /// A TypeOrMethodDef> coded token - /// A or null if is invalid - public ITypeOrMethodDef ResolveTypeOrMethodDef(uint codedToken) { - if (!CodedToken.TypeOrMethodDef.Decode(codedToken, out uint token)) - return null; - uint rid = MDToken.ToRID(token); - return MDToken.ToTable(token) switch { - Table.TypeDef => ResolveTypeDef(rid), - Table.Method => ResolveMethod(rid), - _ => null, - }; - } - - /// - /// Reads a signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// A new instance or null if - /// is invalid. - public CallingConventionSig ReadSignature(uint sig) => SignatureReader.ReadSig(this, sig, new GenericParamContext()); - - /// - /// Reads a signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public CallingConventionSig ReadSignature(uint sig, GenericParamContext gpContext) => SignatureReader.ReadSig(this, sig, gpContext); - - /// - /// Reads a type signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// A new instance or null if - /// is invalid. - public TypeSig ReadTypeSignature(uint sig) => SignatureReader.ReadTypeSig(this, sig, new GenericParamContext()); - - /// - /// Reads a type signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext) => SignatureReader.ReadTypeSig(this, sig, gpContext); - - /// - /// Reads a type signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// If there's any extra data after the signature, it's saved - /// here, else this will be null - /// A new instance or null if - /// is invalid. - public TypeSig ReadTypeSignature(uint sig, out byte[] extraData) => SignatureReader.ReadTypeSig(this, sig, new GenericParamContext(), out extraData); - - /// - /// Reads a type signature from the #Blob stream - /// - /// #Blob stream offset of signature - /// If there's any extra data after the signature, it's saved - /// here, else this will be null - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public TypeSig ReadTypeSignature(uint sig, GenericParamContext gpContext, out byte[] extraData) => SignatureReader.ReadTypeSig(this, sig, gpContext, out extraData); - - /// - /// Reads a from the blob - /// - /// Table of owner - /// Row ID of owner - /// Generic parameter context - /// A new instance or null if there's no field - /// marshal for this owner. - internal MarshalType ReadMarshalType(Table table, uint rid, GenericParamContext gpContext) { - if (!TablesStream.TryReadFieldMarshalRow(Metadata.GetFieldMarshalRid(table, rid), out var row)) - return null; - return MarshalBlobReader.Read(this, row.NativeType, gpContext); - } - - /// - /// Reads a CIL method body - /// - /// Method parameters - /// 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) => ReadCilBody(parameters, rva, new GenericParamContext()); - - /// - /// Reads a CIL method body - /// - /// Method parameters - /// RVA - /// Generic parameter context - /// 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, GenericParamContext gpContext) { - if (rva == 0) - return new CilBody(); - - // Create a full stream so position will be the real position in the file. This - // is important when reading exception handlers since those must be 4-byte aligned. - // 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)offset; - return MethodBodyReader.CreateCilBody(this, reader, parameters, gpContext, Context); - } - - /// - /// Returns the owner type of a field - /// - /// The field - /// The owner type or null if none - 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) => 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) => 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) => 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) => 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) => 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) => ResolveMethod(Metadata.GetOwnerOfParam(pd.OrigRid)); - - /// - /// Reads a module - /// - /// File rid - /// The assembly owning the module we should read - /// A new instance or null if - /// is invalid or if it's not a .NET module. - internal ModuleDefMD ReadModule(uint fileRid, AssemblyDef owner) { - var fileDef = ResolveFile(fileRid); - if (fileDef is null) - return null; - if (!fileDef.ContainsMetadata) - return null; - var fileName = GetValidFilename(GetBaseDirectoryOfImage(), UTF8String.ToSystemString(fileDef.Name)); - if (fileName is null) - return null; - ModuleDefMD module; - try { - module = Load(fileName); - } - catch { - module = null; - } - if (module is not null) { - // share context - module.context = context; - - var asm = module.Assembly; - if (asm is not null && asm != owner) - asm.Modules.Remove(module); - } - return module; - } - - /// - /// Gets a list of all File rids that are .NET modules. Call - /// to read one of these modules. - /// - /// A new instance - internal RidList GetModuleRidList() { - if (moduleRidList is null) - InitializeModuleList(); - return moduleRidList.Value; - } - - void InitializeModuleList() { - if (moduleRidList is not null) - return; - uint rows = TablesStream.FileTable.Rows; - var newModuleRidList = new List((int)rows); - - var baseDir = GetBaseDirectoryOfImage(); - for (uint fileRid = 1; fileRid <= rows; fileRid++) { - var fileDef = ResolveFile(fileRid); - if (fileDef is null) - continue; // Should never happen - if (!fileDef.ContainsMetadata) - continue; - var pathName = GetValidFilename(baseDir, UTF8String.ToSystemString(fileDef.Name)); - if (pathName is not null) - newModuleRidList.Add(fileRid); - } - Interlocked.CompareExchange(ref moduleRidList, new StrongBox(RidList.Create(newModuleRidList)), null); - } - - /// - /// Concatenates the inputs and returns the result if it's a valid path - /// - /// Base dir - /// 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 is null) - return null; - - string pathName; - try { - if (name.IndexOfAny(Path.GetInvalidPathChars()) >= 0) - return null; - pathName = Path.Combine(baseDir, name); - if (pathName != Path.GetFullPath(pathName)) - return null; - if (!File.Exists(pathName)) - return null; - } - catch { - return null; - } - - return pathName; - } - - /// - /// Gets the base directory where this .NET module is located on disk - /// - /// Base directory or null if unknown or if an error occurred - string GetBaseDirectoryOfImage() { - var imageFileName = Location; - if (string.IsNullOrEmpty(imageFileName)) - return null; - try { - return Path.GetDirectoryName(imageFileName); - } - catch (IOException) { - } - catch (ArgumentException) { - } - return null; - } - - /// - /// Creates a instance - /// - /// ManifestResource rid - /// A new instance - Resource CreateResource(uint rid) { - if (!TablesStream.TryReadManifestResourceRow(rid, out var row)) - return new EmbeddedResource(UTF8String.Empty, Array2.Empty(), 0) { Rid = rid }; - - if (!CodedToken.Implementation.Decode(row.Implementation, out MDToken token)) - return new EmbeddedResource(UTF8String.Empty, Array2.Empty(), 0) { Rid = rid }; - - var mr = ResolveManifestResource(rid); - if (mr is null) - return new EmbeddedResource(UTF8String.Empty, Array2.Empty(), 0) { Rid = rid }; - - if (token.Rid == 0) { - if (TryCreateResourceStream(mr.Offset, out var dataReaderFactory, out uint resourceOffset, out uint resourceLength)) - return new EmbeddedResourceMD(this, mr, dataReaderFactory, resourceOffset, resourceLength); - return new EmbeddedResourceMD(this, mr, Array2.Empty()); - } - - if (mr.Implementation is FileDef file) - return new LinkedResourceMD(this, mr, file); - - if (mr.Implementation is AssemblyRef asmRef) - return new AssemblyLinkedResourceMD(this, mr, asmRef); - - return new EmbeddedResourceMD(this, mr, Array2.Empty()); - } - - // 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; - resourceLength = 0; - - try { - var peImage = metadata.PEImage; - var cor20Header = metadata.ImageCor20Header; - var resources = cor20Header.Resources; - if (resources.VirtualAddress == 0 || resources.Size == 0) - return false; - var fullReader = peImage.CreateReader(); - - var resourcesBaseOffs = (uint)peImage.ToFileOffset(resources.VirtualAddress); - if (resourcesBaseOffs == 0 || (ulong)resourcesBaseOffs + offset > uint.MaxValue) - return false; - if ((ulong)offset + 4 > resources.Size) - return false; - if ((ulong)resourcesBaseOffs + offset + 4 > fullReader.Length) - return false; - fullReader.Position = resourcesBaseOffs + offset; - resourceLength = fullReader.ReadUInt32(); // Could throw - resourceOffset = fullReader.Position; - if (resourceLength == 0 || (ulong)fullReader.Position + resourceLength > fullReader.Length) - return false; - if ((ulong)fullReader.Position - resourcesBaseOffs + resourceLength - 1 >= resources.Size) - return false; - - if (peImage.MayHaveInvalidAddresses) { - var rsrcReader = peImage.CreateReader((FileOffset)fullReader.Position, resourceLength); - for (; rsrcReader.Position < rsrcReader.Length; rsrcReader.Position += Math.Min(rsrcReader.BytesLeft, 0x1000)) - rsrcReader.ReadByte(); // Could throw - rsrcReader.Position = rsrcReader.Length - 1; // length is never 0 if we're here - rsrcReader.ReadByte(); // Could throw - } - - dataReaderFactory = peImage.DataReaderFactory; - return true; - } - catch (IOException) { - } - catch (AccessViolationException) { - } - return false; - } - - /// - /// Reads a - /// - /// Custom attribute rid - /// A new instance or null if - /// is invalid - public CustomAttribute ReadCustomAttribute(uint caRid) => ReadCustomAttribute(caRid, new GenericParamContext()); - - /// - /// Reads a - /// - /// Custom attribute rid - /// Generic parameter context - /// A new instance or null if - /// is invalid - public CustomAttribute ReadCustomAttribute(uint caRid, GenericParamContext gpContext) { - if (!TablesStream.TryReadCustomAttributeRow(caRid, out var caRow)) - return null; - return CustomAttributeReader.Read(this, ResolveCustomAttributeType(caRow.Type, gpContext), caRow.Value, gpContext); - } - - /// - /// Reads data somewhere in the address space of the image - /// - /// RVA of data - /// Size of data - /// All the data or null if or - /// is invalid - public byte[] ReadDataAt(RVA rva, int size) { - if (size < 0) - return null; - var peImage = Metadata.PEImage; - var reader = peImage.CreateReader(rva, (uint)size); - if (reader.Length < size) - return null; - return reader.ReadBytes(size); - } - - /// - /// Gets the native entry point or 0 if none - /// - public RVA GetNativeEntryPoint() { - var cor20Header = Metadata.ImageCor20Header; - if ((cor20Header.Flags & ComImageFlags.NativeEntryPoint) == 0) - return 0; - return (RVA)cor20Header.EntryPointToken_or_RVA; - } - - /// - /// Gets the managed entry point (a Method or a File) or null if none - /// - public IManagedEntryPoint GetManagedEntryPoint() { - var cor20Header = Metadata.ImageCor20Header; - if ((cor20Header.Flags & ComImageFlags.NativeEntryPoint) != 0) - return null; - return ResolveToken(cor20Header.EntryPointToken_or_RVA) as IManagedEntryPoint; - } - - /// - /// Reads a new instance. This one is not cached. - /// - /// Row ID - /// A new instance - 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) => new MethodDefMD(this, rid); - - /// - /// Reads a new instance. This one is not cached. - /// - /// Row ID - /// A new instance - 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) => new PropertyDefMD(this, rid); - - /// - /// Reads a new instance. This one is not cached. - /// - /// Row ID - /// A new instance - 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) => new GenericParamMD(this, rid); - - /// - /// Reads a new instance. This one is not cached. - /// - /// Row ID - /// A new instance - internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid) => new GenericParamConstraintMD(this, rid, new GenericParamContext()); - - /// - /// Reads a new instance. This one is not cached. - /// - /// Row ID - /// Generic parameter context - /// A new instance - internal GenericParamConstraintMD ReadGenericParamConstraint(uint rid, GenericParamContext gpContext) => new GenericParamConstraintMD(this, rid, gpContext); - - /// - /// Reads a method body - /// - /// Method - /// Method RVA - /// Method impl attrs - /// Generic parameter context - /// A or null if none - internal MethodBody ReadMethodBody(MethodDefMD method, RVA rva, MethodImplAttributes implAttrs, GenericParamContext gpContext) { - var mDec = methodDecrypter; - 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; - } - - if (rva == 0) - return null; - var codeType = implAttrs & MethodImplAttributes.CodeTypeMask; - if (codeType == MethodImplAttributes.IL) - return InitializeBodyFromPdb(method, ReadCilBody(method.Parameters, rva, gpContext)); - if (codeType == MethodImplAttributes.Native) - return new NativeMethodBody(rva); - return null; - } - - /// - /// Updates with the PDB info (if any) - /// - /// Owner method - /// Method body - /// Returns originak value - CilBody InitializeBodyFromPdb(MethodDefMD method, CilBody body) { - var ps = pdbState; - if (ps is not null) - ps.InitializeMethodBody(this, method, body); - return body; - } - - internal void InitializeCustomDebugInfos(MethodDefMD method, CilBody body, IList customDebugInfos) { - if (body is null) - return; - - var ps = pdbState; - if (ps is not null) - ps.InitializeCustomDebugInfos(method, body, customDebugInfos); - } - - /// - /// Reads a string from the #US heap - /// - /// String token - /// A non-null string - public string ReadUserString(uint token) { - var sDec = stringDecrypter; - if (sDec is not null) { - var s = sDec.ReadUserString(token); - if (s is not null) - return s; - } - return USStream.ReadNoNull(token & 0x00FFFFFF); - } - - internal MethodExportInfo GetExportInfo(uint methodRid) { - if (methodExportInfoProvider is 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. - /// - /// Filename - 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. - /// - /// Filename - /// Writer options - public void NativeWrite(string filename, DNW.NativeModuleWriterOptions options) { - var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this, optimizeImageSize: true)); - writer.Write(filename); - } - - /// - /// Writes the mixed-mode module to a stream. - /// - /// Destination stream - public void NativeWrite(Stream dest) => NativeWrite(dest, null); - - /// - /// Writes the mixed-mode module to a stream. - /// - /// Destination stream - /// Writer options - public void NativeWrite(Stream dest, DNW.NativeModuleWriterOptions options) { - var writer = new DNW.NativeModuleWriter(this, options ?? new DNW.NativeModuleWriterOptions(this, optimizeImageSize: true)); - writer.Write(dest); - } - - /// - /// Reads data from the #Blob. The following columns are returned: - /// Field.Signature - /// Method.Signature - /// MemberRef.Signature - /// Constant.Value - /// CustomAttribute.Value - /// FieldMarshal.NativeType - /// DeclSecurity.PermissionSet - /// StandAloneSig.Signature - /// Property.Type - /// TypeSpec.Signature - /// Assembly.PublicKey - /// AssemblyRef.PublicKeyOrToken - /// File.HashValue - /// MethodSpec.Instantiation - /// - /// A token - /// The value in the #Blob or null if is invalid - public byte[] ReadBlob(uint token) { - uint rid = MDToken.ToRID(token); - switch (MDToken.ToTable(token)) { - case Table.Field: - if (!TablesStream.TryReadFieldRow(rid, out var fieldRow)) - break; - return BlobStream.Read(fieldRow.Signature); - - case Table.Method: - if (!TablesStream.TryReadMethodRow(rid, out var methodRow)) - break; - return BlobStream.Read(methodRow.Signature); - - case Table.MemberRef: - if (!TablesStream.TryReadMemberRefRow(rid, out var mrRow)) - break; - return BlobStream.Read(mrRow.Signature); - - case Table.Constant: - if (!TablesStream.TryReadConstantRow(rid, out var constRow)) - break; - return BlobStream.Read(constRow.Value); - - case Table.CustomAttribute: - if (!TablesStream.TryReadCustomAttributeRow(rid, out var caRow)) - break; - return BlobStream.Read(caRow.Value); - - case Table.FieldMarshal: - if (!TablesStream.TryReadFieldMarshalRow(rid, out var fmRow)) - break; - return BlobStream.Read(fmRow.NativeType); - - case Table.DeclSecurity: - if (!TablesStream.TryReadDeclSecurityRow(rid, out var dsRow)) - break; - return BlobStream.Read(dsRow.PermissionSet); - - case Table.StandAloneSig: - if (!TablesStream.TryReadStandAloneSigRow(rid, out var sasRow)) - break; - return BlobStream.Read(sasRow.Signature); - - case Table.Property: - if (!TablesStream.TryReadPropertyRow(rid, out var propRow)) - break; - return BlobStream.Read(propRow.Type); - - case Table.TypeSpec: - if (!TablesStream.TryReadTypeSpecRow(rid, out var tsRow)) - break; - return BlobStream.Read(tsRow.Signature); - - case Table.Assembly: - if (!TablesStream.TryReadAssemblyRow(rid, out var asmRow)) - break; - return BlobStream.Read(asmRow.PublicKey); - - case Table.AssemblyRef: - // HashValue is also in the #Blob but the user has to read it some other way - if (!TablesStream.TryReadAssemblyRefRow(rid, out var asmRefRow)) - break; - return BlobStream.Read(asmRefRow.PublicKeyOrToken); - - case Table.File: - if (!TablesStream.TryReadFileRow(rid, out var fileRow)) - break; - return BlobStream.Read(fileRow.HashValue); - - case Table.MethodSpec: - if (!TablesStream.TryReadMethodSpecRow(rid, out var msRow)) - break; - return BlobStream.Read(msRow.Instantiation); - } - - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/ModuleKind.cs b/Plugins/dnlib/DotNet/ModuleKind.cs deleted file mode 100644 index 9cd42c9..0000000 --- a/Plugins/dnlib/DotNet/ModuleKind.cs +++ /dev/null @@ -1,28 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Module kind - /// - public enum ModuleKind { - /// - /// Console UI module - /// - Console, - - /// - /// Windows GUI module - /// - Windows, - - /// - /// DLL module - /// - Dll, - - /// - /// Netmodule (it has no assembly manifest) - /// - NetModule, - } -} diff --git a/Plugins/dnlib/DotNet/ModuleLoader.cs b/Plugins/dnlib/DotNet/ModuleLoader.cs deleted file mode 100644 index 16ba055..0000000 --- a/Plugins/dnlib/DotNet/ModuleLoader.cs +++ /dev/null @@ -1,931 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet.Emit; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.PE; -using dnlib.Threading; -using dnlib.W32Resources; - -namespace dnlib.DotNet { - readonly struct ModuleLoader { - readonly ModuleDef module; - readonly ICancellationToken cancellationToken; - readonly Dictionary seen; - readonly Stack stack; - - ModuleLoader(ModuleDef module, ICancellationToken cancellationToken) { - const int CAPACITY = 0x4000; - this.module = module; - this.cancellationToken = cancellationToken; - seen = new Dictionary(CAPACITY); - stack = new Stack(CAPACITY); - } - - public static void LoadAll(ModuleDef module, ICancellationToken cancellationToken) => - new ModuleLoader(module, cancellationToken).Load(); - - void Add(UTF8String a) { } - void Add(Guid? a) { } - void Add(ushort a) { } - void Add(AssemblyHashAlgorithm a) { } - void Add(Version a) { } - void Add(AssemblyAttributes a) { } - void Add(PublicKeyBase a) { } - void Add(RVA a) { } - void Add(IManagedEntryPoint a) { } - void Add(string a) { } - void Add(WinMDStatus a) { } - void Add(TypeAttributes a) { } - void Add(FieldAttributes a) { } - void Add(uint? a) { } - void Add(byte[] a) { } - void Add(MethodImplAttributes a) { } - void Add(MethodAttributes a) { } - void Add(MethodSemanticsAttributes a) { } - void Add(ParamAttributes a) { } - void Add(ElementType a) { } - void Add(SecurityAction a) { } - void Add(EventAttributes a) { } - void Add(PropertyAttributes a) { } - void Add(PInvokeAttributes a) { } - void Add(FileAttributes a) { } - void Add(ManifestResourceAttributes a) { } - void Add(GenericParamAttributes a) { } - void Add(NativeType a) { } - - void Load() { - LoadAllTables(); - Load(module); - Process(); - } - - void Process() { - while (stack.Count != 0) { - if (cancellationToken is not null) - cancellationToken.ThrowIfCancellationRequested(); - var o = stack.Pop(); - LoadObj(o); - } - } - - void LoadAllTables() { - var resolver = module as ITokenResolver; - 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 is null) - break; - Add(o); - Process(); - } - } - } - - void LoadObj(object o) { - if (o is TypeSig ts) { - Load(ts); - return; - } - - if (o is IMDTokenProvider mdt) { - Load(mdt); - return; - } - - if (o is CustomAttribute ca) { - Load(ca); - return; - } - - if (o is SecurityAttribute sa) { - Load(sa); - return; - } - - if (o is CANamedArgument na) { - Load(na); - return; - } - - if (o is Parameter p) { - Load(p); - return; - } - - if (o is PdbMethod pdbMethod) { - Load(pdbMethod); - return; - } - - if (o is ResourceDirectory rd) { - Load(rd); - return; - } - - if (o is ResourceData rdata) { - Load(rdata); - return; - } - - Debug.Fail("Unknown type"); - } - - void Load(TypeSig ts) { - if (ts is null) - return; - Add(ts.Next); - - switch (ts.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.ValueType: - case ElementType.Class: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - Add(((TypeDefOrRefSig)ts).TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - var vsig = (GenericSig)ts; - Add(vsig.OwnerType); - Add(vsig.OwnerMethod); - break; - - case ElementType.GenericInst: - var gis = (GenericInstSig)ts; - Add(gis.GenericType); - Add(gis.GenericArguments); - break; - - case ElementType.FnPtr: - var fpsig = (FnPtrSig)ts; - Add(fpsig.Signature); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - var cmod = (ModifierSig)ts; - Add(cmod.Modifier); - break; - - case ElementType.End: - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.ValueArray: - case ElementType.SZArray: - case ElementType.Module: - case ElementType.Pinned: - case ElementType.Sentinel: - case ElementType.R: - case ElementType.Internal: - default: - break; - } - } - - void Load(IMDTokenProvider mdt) { - if (mdt is null) - return; - switch (mdt.MDToken.Table) { - case Table.Module: Load((ModuleDef)mdt); break; - case Table.TypeRef: Load((TypeRef)mdt); break; - case Table.TypeDef: Load((TypeDef)mdt); break; - case Table.Field: Load((FieldDef)mdt); break; - case Table.Method: Load((MethodDef)mdt); break; - case Table.Param: Load((ParamDef)mdt); break; - case Table.InterfaceImpl: Load((InterfaceImpl)mdt); break; - case Table.MemberRef: Load((MemberRef)mdt); break; - case Table.Constant: Load((Constant)mdt); break; - case Table.DeclSecurity: Load((DeclSecurity)mdt); break; - case Table.ClassLayout: Load((ClassLayout)mdt); break; - case Table.StandAloneSig: Load((StandAloneSig)mdt); break; - case Table.Event: Load((EventDef)mdt); break; - case Table.Property: Load((PropertyDef)mdt); break; - case Table.ModuleRef: Load((ModuleRef)mdt); break; - case Table.TypeSpec: Load((TypeSpec)mdt); break; - case Table.ImplMap: Load((ImplMap)mdt); break; - case Table.Assembly: Load((AssemblyDef)mdt); break; - case Table.AssemblyRef: Load((AssemblyRef)mdt); break; - case Table.File: Load((FileDef)mdt); break; - case Table.ExportedType: Load((ExportedType)mdt); break; - case Table.GenericParam: Load((GenericParam)mdt); break; - case Table.MethodSpec: Load((MethodSpec)mdt); break; - case Table.GenericParamConstraint: Load((GenericParamConstraint)mdt); break; - - case Table.ManifestResource: - var rsrc = mdt as Resource; - if (rsrc is not null) { - Load(rsrc); - break; - } - - var mr = mdt as ManifestResource; - if (mr is not null) { - Load(mr); - break; - } - - Debug.Fail("Unknown ManifestResource"); - break; - - case Table.FieldPtr: - case Table.MethodPtr: - case Table.ParamPtr: - case Table.CustomAttribute: - case Table.FieldMarshal: - case Table.FieldLayout: - case Table.EventMap: - case Table.EventPtr: - case Table.PropertyMap: - case Table.PropertyPtr: - case Table.MethodSemantics: - case Table.MethodImpl: - case Table.FieldRVA: - case Table.ENCLog: - case Table.ENCMap: - case Table.AssemblyProcessor: - case Table.AssemblyOS: - 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: - Debug.Fail("Unknown type"); - break; - } - } - - void Load(ModuleDef obj) { - if (obj is null || obj != module) - return; - Add(obj.Generation); - Add(obj.Name); - Add(obj.Mvid); - Add(obj.EncId); - Add(obj.EncBaseId); - Add(obj.CustomAttributes); - Add(obj.Assembly); - Add(obj.Types); - Add(obj.ExportedTypes); - Add(obj.NativeEntryPoint); - Add(obj.ManagedEntryPoint); - Add(obj.Resources); - Add(obj.VTableFixups); - Add(obj.Location); - Add(obj.Win32Resources); - Add(obj.RuntimeVersion); - Add(obj.WinMDStatus); - Add(obj.RuntimeVersionWinMD); - Add(obj.WinMDVersion); - Add(obj.PdbState); - } - - void Load(TypeRef obj) { - if (obj is null) - return; - Add(obj.ResolutionScope); - Add(obj.Name); - Add(obj.Namespace); - Add(obj.CustomAttributes); - } - - void Load(TypeDef obj) { - if (obj is null) - return; - Add(obj.Module2); - Add(obj.Attributes); - Add(obj.Name); - Add(obj.Namespace); - Add(obj.BaseType); - Add(obj.Fields); - Add(obj.Methods); - Add(obj.GenericParameters); - Add(obj.Interfaces); - Add(obj.DeclSecurities); - Add(obj.ClassLayout); - Add(obj.DeclaringType); - Add(obj.DeclaringType2); - Add(obj.NestedTypes); - Add(obj.Events); - Add(obj.Properties); - Add(obj.CustomAttributes); - } - - void Load(FieldDef obj) { - if (obj is null) - return; - Add(obj.CustomAttributes); - Add(obj.Attributes); - Add(obj.Name); - Add(obj.Signature); - Add(obj.FieldOffset); - Add(obj.MarshalType); - Add(obj.RVA); - Add(obj.InitialValue); - Add(obj.ImplMap); - Add(obj.Constant); - Add(obj.DeclaringType); - } - - void Load(MethodDef obj) { - if (obj is null) - return; - Add(obj.RVA); - Add(obj.ImplAttributes); - Add(obj.Attributes); - Add(obj.Name); - Add(obj.Signature); - Add(obj.ParamDefs); - Add(obj.GenericParameters); - Add(obj.DeclSecurities); - Add(obj.ImplMap); - Add(obj.MethodBody); - Add(obj.CustomAttributes); - Add(obj.Overrides); - Add(obj.DeclaringType); - Add(obj.Parameters); - Add(obj.SemanticsAttributes); - } - - void Load(ParamDef obj) { - if (obj is null) - return; - Add(obj.DeclaringMethod); - Add(obj.Attributes); - Add(obj.Sequence); - Add(obj.Name); - Add(obj.MarshalType); - Add(obj.Constant); - Add(obj.CustomAttributes); - } - - void Load(InterfaceImpl obj) { - if (obj is null) - return; - Add(obj.Interface); - Add(obj.CustomAttributes); - } - - void Load(MemberRef obj) { - if (obj is null) - return; - Add(obj.Class); - Add(obj.Name); - Add(obj.Signature); - Add(obj.CustomAttributes); - } - - void Load(Constant obj) { - if (obj is null) - return; - Add(obj.Type); - var o = obj.Value; - } - - void Load(DeclSecurity obj) { - if (obj is null) - return; - Add(obj.Action); - Add(obj.SecurityAttributes); - Add(obj.CustomAttributes); - obj.GetBlob(); - } - - void Load(ClassLayout obj) { - if (obj is null) - return; - Add(obj.PackingSize); - Add(obj.ClassSize); - } - - void Load(StandAloneSig obj) { - if (obj is null) - return; - Add(obj.Signature); - Add(obj.CustomAttributes); - } - - void Load(EventDef obj) { - if (obj is null) - return; - Add(obj.Attributes); - Add(obj.Name); - Add(obj.EventType); - Add(obj.CustomAttributes); - Add(obj.AddMethod); - Add(obj.InvokeMethod); - Add(obj.RemoveMethod); - Add(obj.OtherMethods); - Add(obj.DeclaringType); - } - - void Load(PropertyDef obj) { - if (obj is null) - return; - Add(obj.Attributes); - Add(obj.Name); - Add(obj.Type); - Add(obj.Constant); - Add(obj.CustomAttributes); - Add(obj.GetMethods); - Add(obj.SetMethods); - Add(obj.OtherMethods); - Add(obj.DeclaringType); - } - - void Load(ModuleRef obj) { - if (obj is null) - return; - Add(obj.Name); - Add(obj.CustomAttributes); - } - - void Load(TypeSpec obj) { - if (obj is null) - return; - Add(obj.TypeSig); - Add(obj.ExtraData); - Add(obj.CustomAttributes); - } - - void Load(ImplMap obj) { - if (obj is null) - return; - Add(obj.Attributes); - Add(obj.Name); - Add(obj.Module); - } - - void Load(AssemblyDef obj) { - if (obj is null) - return; - if (obj.ManifestModule != module) - return; - Add(obj.HashAlgorithm); - Add(obj.Version); - Add(obj.Attributes); - Add(obj.PublicKey); - Add(obj.Name); - Add(obj.Culture); - Add(obj.DeclSecurities); - Add(obj.Modules); - Add(obj.CustomAttributes); - } - - void Load(AssemblyRef obj) { - if (obj is null) - return; - Add(obj.Version); - Add(obj.Attributes); - Add(obj.PublicKeyOrToken); - Add(obj.Name); - Add(obj.Culture); - Add(obj.Hash); - Add(obj.CustomAttributes); - } - - void Load(FileDef obj) { - if (obj is null) - return; - Add(obj.Flags); - Add(obj.Name); - Add(obj.HashValue); - Add(obj.CustomAttributes); - } - - void Load(ExportedType obj) { - if (obj is null) - return; - Add(obj.CustomAttributes); - Add(obj.Attributes); - Add(obj.TypeDefId); - Add(obj.TypeName); - Add(obj.TypeNamespace); - Add(obj.Implementation); - } - - void Load(Resource obj) { - if (obj is null) - return; - - Add(obj.Offset); - Add(obj.Name); - Add(obj.Attributes); - Add(obj.CustomAttributes); - - switch (obj.ResourceType) { - case ResourceType.Embedded: - break; - - case ResourceType.AssemblyLinked: - var ar = (AssemblyLinkedResource)obj; - Add(ar.Assembly); - break; - - case ResourceType.Linked: - var lr = (LinkedResource)obj; - Add(lr.File); - Add(lr.Hash); - break; - - default: - Debug.Fail("Unknown resource"); - break; - } - } - - void Load(ManifestResource obj) { - if (obj is null) - return; - Add(obj.Offset); - Add(obj.Flags); - Add(obj.Name); - Add(obj.Implementation); - Add(obj.CustomAttributes); - } - - void Load(GenericParam obj) { - if (obj is null) - return; - Add(obj.Owner); - Add(obj.Number); - Add(obj.Flags); - Add(obj.Name); - Add(obj.Kind); - Add(obj.GenericParamConstraints); - Add(obj.CustomAttributes); - } - - void Load(MethodSpec obj) { - if (obj is null) - return; - Add(obj.Method); - Add(obj.Instantiation); - Add(obj.CustomAttributes); - } - - void Load(GenericParamConstraint obj) { - if (obj is null) - return; - Add(obj.Owner); - Add(obj.Constraint); - Add(obj.CustomAttributes); - } - - void Load(CANamedArgument obj) { - if (obj is null) - return; - Add(obj.Type); - Add(obj.Name); - Load(obj.Argument); - } - - void Load(Parameter obj) { - if (obj is null) - return; - Add(obj.Type); - } - - void Load(SecurityAttribute obj) { - if (obj is null) - return; - Add(obj.AttributeType); - Add(obj.NamedArguments); - } - - void Load(CustomAttribute obj) { - if (obj is null) - return; - Add(obj.Constructor); - Add(obj.RawData); - Add(obj.ConstructorArguments); - Add(obj.NamedArguments); - } - - void Load(MethodOverride obj) { - Add(obj.MethodBody); - Add(obj.MethodDeclaration); - } - - void AddCAValue(object obj) { - if (obj is CAArgument) { - Load((CAArgument)obj); - return; - } - - if (obj is IList list) { - Add(list); - return; - } - - if (obj is IMDTokenProvider md) { - Add(md); - return; - } - } - - void Load(CAArgument obj) { - Add(obj.Type); - AddCAValue(obj.Value); - } - - void Load(PdbMethod obj) { } - - void Load(ResourceDirectory obj) { - if (obj is null) - return; - Add(obj.Directories); - Add(obj.Data); - } - - void Load(ResourceData obj) { } - - void AddToStack(T t) where T : class { - if (t is null) - return; - if (seen.ContainsKey(t)) - return; - seen[t] = true; - 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(PdbMethod pdbMethod) { } - 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 is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Load(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Load(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(ParameterList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(IList list) { - if (list is null) - return; - foreach (var item in list) - Add(item); - } - - void Add(VTableFixups vtf) { - if (vtf is null) - return; - foreach (var fixup in vtf) { - foreach (var method in fixup) - Add(method); - } - } - - void Add(Win32Resources vtf) { - if (vtf is null) - return; - Add(vtf.Root); - } - - void Add(CallingConventionSig sig) { - if (sig is MethodBaseSig msig) { - Add(msig); - return; - } - - if (sig is FieldSig fsig) { - Add(fsig); - return; - } - - if (sig is LocalSig lsig) { - Add(lsig); - return; - } - - if (sig is GenericInstMethodSig gsig) { - Add(gsig); - return; - } - - Debug.Assert(sig is null); - } - - void Add(MethodBaseSig msig) { - if (msig is null) - return; - Add(msig.ExtraData); - Add(msig.RetType); - Add(msig.Params); - Add(msig.ParamsAfterSentinel); - } - - void Add(FieldSig fsig) { - if (fsig is null) - return; - Add(fsig.ExtraData); - Add(fsig.Type); - } - - void Add(LocalSig lsig) { - if (lsig is null) - return; - Add(lsig.ExtraData); - Add(lsig.Locals); - } - - void Add(GenericInstMethodSig gsig) { - if (gsig is null) - return; - Add(gsig.ExtraData); - Add(gsig.GenericArguments); - } - - void Add(MarshalType mt) { - if (mt is null) - return; - Add(mt.NativeType); - } - - void Add(MethodBody mb) { - if (mb is CilBody cilBody) { - Add(cilBody); - return; - } - - if (mb is NativeMethodBody nb) { - Add(nb); - return; - } - - Debug.Assert(mb is null, "Unknown method body"); - } - - void Add(NativeMethodBody body) { - if (body is null) - return; - Add(body.RVA); - } - - void Add(CilBody body) { - if (body is null) - return; - Add(body.Instructions); - Add(body.ExceptionHandlers); - Add(body.Variables); - Add(body.PdbMethod); - } - - void Add(Instruction instr) { - if (instr is null) - return; - - if (instr.Operand is IMDTokenProvider mdt) { - Add(mdt); - return; - } - - if (instr.Operand is Parameter p) { - Add(p); - return; - } - - if (instr.Operand is Local l) { - Add(l); - return; - } - - if (instr.Operand is CallingConventionSig csig) { - Add(csig); - return; - } - } - - void Add(ExceptionHandler eh) { - if (eh is null) - return; - Add(eh.CatchType); - } - - void Add(Local local) { - if (local is null) - return; - Add(local.Type); - } - - void Add(PdbState state) { - if (state is null) - return; - Add(state.UserEntryPoint); - } - } -} diff --git a/Plugins/dnlib/DotNet/ModuleRef.cs b/Plugins/dnlib/DotNet/ModuleRef.cs deleted file mode 100644 index 22cacc6..0000000 --- a/Plugins/dnlib/DotNet/ModuleRef.cs +++ /dev/null @@ -1,203 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the ModuleRef table - /// - public abstract class ModuleRef : IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation, IResolutionScope, IModule, IOwnerModule { - /// - /// The row id in its table - /// - protected uint rid; - - /// - /// The owner module - /// - protected ModuleDef module; - - /// - public MDToken MDToken => new MDToken(Table.ModuleRef, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 12; - - /// - public int MemberRefParentTag => 2; - - /// - public int ResolutionScopeTag => 1; - - /// - public ScopeType ScopeType => ScopeType.ModuleRef; - - /// - public string ScopeName => FullName; - - /// - /// From column ModuleRef.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// 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 => 12; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 ModuleDef Module => module; - - /// - /// Gets the definition module, i.e., the module which it references, or null - /// if the module can't be found. - /// - public ModuleDef DefinitionModule { - get { - if (module is null) - return null; - var n = name; - if (UTF8String.CaseInsensitiveEquals(n, module.Name)) - return module; - return DefinitionAssembly?.FindModule(n); - } - } - - /// - /// 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 => module?.Assembly; - - /// - public string FullName => UTF8String.ToSystemStringOrEmpty(name); - - /// - public override string ToString() => FullName; - } - - /// - /// A ModuleRef row created by the user and not present in the original .NET file - /// - public class ModuleRefUser : ModuleRef { - /// - /// Constructor - /// - /// Owner module - public ModuleRefUser(ModuleDef module) - : this(module, UTF8String.Empty) { - } - - /// - /// Constructor - /// - /// Owner module - /// Module name - public ModuleRefUser(ModuleDef module, UTF8String name) { - this.module = module; - this.name = name; - } - } - - /// - /// Created from a row in the ModuleRef table - /// - sealed class ModuleRefMD : ModuleRef, 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.ModuleRef, 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); - } - - /// - /// Constructor - /// - /// The module which contains this ModuleRef row - /// Row ID - /// If is null - /// If is invalid - public ModuleRefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ModuleRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"ModuleRef rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - module = readerModule; - bool b = readerModule.TablesStream.TryReadModuleRefRow(origRid, out var row); - Debug.Assert(b); - name = readerModule.StringsStream.ReadNoNull(row.Name); - } - } -} diff --git a/Plugins/dnlib/DotNet/NativeType.cs b/Plugins/dnlib/DotNet/NativeType.cs deleted file mode 100644 index b1a78e4..0000000 --- a/Plugins/dnlib/DotNet/NativeType.cs +++ /dev/null @@ -1,109 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Native types used by field marshals. See CorHdr.h/CorNativeType - /// - public enum NativeType : uint { - /// Deprecated - End = 0x00, - /// void - Void = 0x01, - /// bool - Boolean = 0x02, - /// int8 - I1 = 0x03, - /// unsigned int8 - U1 = 0x04, - /// int16 - I2 = 0x05, - /// unsigned int16 - U2 = 0x06, - /// int32 - I4 = 0x07, - /// unsigned int32 - U4 = 0x08, - /// int64 - I8 = 0x09, - /// unsigned int64 - U8 = 0x0A, - /// float32 - R4 = 0x0B, - /// float64 - R8 = 0x0C, - /// syschar - SysChar = 0x0D, - /// variant - Variant = 0x0E, - /// currency - Currency = 0x0F, - /// ptr - Ptr = 0x10, - /// decimal - Decimal = 0x11, - /// date - Date = 0x12, - /// bstr - BStr = 0x13, - /// lpstr - LPStr = 0x14, - /// lpwstr - LPWStr = 0x15, - /// lptstr - LPTStr = 0x16, - /// fixed sysstring - FixedSysString = 0x17, - /// objectref - ObjectRef = 0x18, - /// iunknown - IUnknown = 0x19, - /// idispatch - IDispatch = 0x1A, - /// struct - Struct = 0x1B, - /// interface - IntF = 0x1C, - /// safearray - SafeArray = 0x1D, - /// fixed array - FixedArray = 0x1E, - /// int - Int = 0x1F, - /// uint - UInt = 0x20, - /// nested struct - NestedStruct = 0x21, - /// byvalstr - ByValStr = 0x22, - /// ansi bstr - ANSIBStr = 0x23, - /// tbstr - TBStr = 0x24, - /// variant bool - VariantBool = 0x25, - /// func - Func = 0x26, - /// as any - ASAny = 0x28, - /// array - Array = 0x2A, - /// lpstruct - LPStruct = 0x2B, - /// custom marshaler - CustomMarshaler = 0x2C, - /// error - Error = 0x2D, - /// iinspectable - IInspectable = 0x2E, - /// hstring - HString = 0x2F, - /// UTF-8 encoded string - LPUTF8Str = 0x30, - /// first invalid element type - Max = 0x50, - /// Value wasn't present in the blob - NotInitialized = 0xFFFFFFFE, - /// Raw marshal blob type - RawBlob = 0xFFFFFFFF, - } -} diff --git a/Plugins/dnlib/DotNet/NullResolver.cs b/Plugins/dnlib/DotNet/NullResolver.cs deleted file mode 100644 index 805097d..0000000 --- a/Plugins/dnlib/DotNet/NullResolver.cs +++ /dev/null @@ -1,25 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// A resolver that always fails - /// - public sealed class NullResolver : IAssemblyResolver, IResolver { - /// - /// The one and only instance of this type - /// - public static readonly NullResolver Instance = new NullResolver(); - - NullResolver() { - } - - /// - public AssemblyDef Resolve(IAssembly assembly, ModuleDef sourceModule) => null; - - /// - public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) => null; - - /// - public IMemberForwarded Resolve(MemberRef memberRef) => null; - } -} diff --git a/Plugins/dnlib/DotNet/PInvokeAttributes.cs b/Plugins/dnlib/DotNet/PInvokeAttributes.cs deleted file mode 100644 index 28bf59f..0000000 --- a/Plugins/dnlib/DotNet/PInvokeAttributes.cs +++ /dev/null @@ -1,61 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// P/Invoke attributes, see CorHdr.h/CorPinvokeMap - /// - [Flags] - public enum PInvokeAttributes : ushort { - /// Pinvoke is to use the member name as specified. - NoMangle = 0x0001, - - /// Use this mask to retrieve the CharSet information. - CharSetMask = 0x0006, - /// - CharSetNotSpec = 0x0000, - /// - CharSetAnsi = 0x0002, - /// - CharSetUnicode = 0x0004, - /// - CharSetAuto = 0x0006, - - /// - BestFitUseAssem = 0x0000, - /// - BestFitEnabled = 0x0010, - /// - BestFitDisabled = 0x0020, - /// - BestFitMask = 0x0030, - - /// - ThrowOnUnmappableCharUseAssem = 0x0000, - /// - ThrowOnUnmappableCharEnabled = 0x1000, - /// - ThrowOnUnmappableCharDisabled = 0x2000, - /// - ThrowOnUnmappableCharMask = 0x3000, - - /// Information about target function. Not relevant for fields. - SupportsLastError = 0x0040, - - /// - CallConvMask = 0x0700, - /// Pinvoke will use native callconv appropriate to target windows platform. - CallConvWinapi = 0x0100, - /// - CallConvCdecl = 0x0200, - /// - CallConvStdcall = 0x0300, - /// - CallConvStdCall = CallConvStdcall, - /// In M9, pinvoke will raise exception. - CallConvThiscall = 0x0400, - /// - CallConvFastcall = 0x0500, - } -} diff --git a/Plugins/dnlib/DotNet/ParamAttributes.cs b/Plugins/dnlib/DotNet/ParamAttributes.cs deleted file mode 100644 index 39146fc..0000000 --- a/Plugins/dnlib/DotNet/ParamAttributes.cs +++ /dev/null @@ -1,27 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Parameter flags. See CorHdr.h/CorParamAttr - /// - [Flags] - public enum ParamAttributes : ushort { - /// Param is [In] - 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, - - /// Param has default value. - HasDefault = 0x1000, - /// Param has FieldMarshal. - HasFieldMarshal = 0x2000, - } -} diff --git a/Plugins/dnlib/DotNet/ParamDef.cs b/Plugins/dnlib/DotNet/ParamDef.cs deleted file mode 100644 index 1b001d0..0000000 --- a/Plugins/dnlib/DotNet/ParamDef.cs +++ /dev/null @@ -1,419 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Param table - /// - [DebuggerDisplay("{Sequence} {Name}")] - public abstract class ParamDef : IHasConstant, IHasCustomAttribute, IHasFieldMarshal, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.Param, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasConstantTag => 1; - - /// - public int HasCustomAttributeTag => 4; - - /// - public int HasFieldMarshalTag => 1; - - /// - /// Gets the declaring method - /// - public MethodDef DeclaringMethod { - get => declaringMethod; - internal set => declaringMethod = value; - } - /// - protected MethodDef declaringMethod; - - /// - /// From column Param.Flags - /// - public ParamAttributes Attributes { - get => (ParamAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column Param.Sequence - /// - public ushort Sequence { - get => sequence; - set => sequence = value; - } - /// - protected ushort sequence; - - /// - /// From column Param.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - public MarshalType MarshalType { - get { - if (!marshalType_isInitialized) - InitializeMarshalType(); - return marshalType; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - marshalType = value; - marshalType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected MarshalType marshalType; - /// - protected bool marshalType_isInitialized; - - void InitializeMarshalType() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (marshalType_isInitialized) - return; - marshalType = GetMarshalType_NoLock(); - marshalType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual MarshalType GetMarshalType_NoLock() => null; - - /// Reset - protected void ResetMarshalType() => marshalType_isInitialized = false; - - /// - public Constant Constant { - get { - if (!constant_isInitialized) - InitializeConstant(); - return constant; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - constant = value; - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected Constant constant; - /// - protected bool constant_isInitialized; - - void InitializeConstant() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (constant_isInitialized) - return; - constant = GetConstant_NoLock(); - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual Constant GetConstant_NoLock() => null; - - /// Reset - protected void ResetConstant() => constant_isInitialized = false; - - /// - /// 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 => 4; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// true if is not null - /// - public bool HasConstant => Constant is not null; - - /// - /// Gets the constant element type or if there's no constant - /// - public ElementType ElementType { - get { - var c = Constant; - return c is null ? ElementType.End : c.Type; - } - } - - /// - /// true if is not null - /// - public bool HasMarshalType => MarshalType is not null; - - /// - public string FullName { - get { - var n = name; - if (UTF8String.IsNullOrEmpty(n)) - return $"A_{sequence}"; - return n.String; - } - } - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, ParamAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool IsIn { - get => ((ParamAttributes)attributes & ParamAttributes.In) != 0; - set => ModifyAttributes(value, ParamAttributes.In); - } - - /// - /// Gets/sets the bit - /// - public bool IsOut { - get => ((ParamAttributes)attributes & ParamAttributes.Out) != 0; - set => ModifyAttributes(value, ParamAttributes.Out); - } - - /// - /// Gets/sets the bit - /// - public bool IsLcid { - get => ((ParamAttributes)attributes & ParamAttributes.Lcid) != 0; - set => ModifyAttributes(value, ParamAttributes.Lcid); - } - - /// - /// Gets/sets the bit - /// - public bool IsRetval { - get => ((ParamAttributes)attributes & ParamAttributes.Retval) != 0; - set => ModifyAttributes(value, ParamAttributes.Retval); - } - - /// - /// Gets/sets the bit - /// - public bool IsOptional { - get => ((ParamAttributes)attributes & ParamAttributes.Optional) != 0; - set => ModifyAttributes(value, ParamAttributes.Optional); - } - - /// - /// Gets/sets the bit - /// - public bool HasDefault { - get => ((ParamAttributes)attributes & ParamAttributes.HasDefault) != 0; - set => ModifyAttributes(value, ParamAttributes.HasDefault); - } - - /// - /// Gets/sets the bit - /// - public bool HasFieldMarshal { - get => ((ParamAttributes)attributes & ParamAttributes.HasFieldMarshal) != 0; - set => ModifyAttributes(value, ParamAttributes.HasFieldMarshal); - } - } - - /// - /// A Param row created by the user and not present in the original .NET file - /// - public class ParamDefUser : ParamDef { - /// - /// Default constructor - /// - public ParamDefUser() { - } - - /// - /// Constructor - /// - /// Name - public ParamDefUser(UTF8String name) - : this(name, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Sequence - public ParamDefUser(UTF8String name, ushort sequence) - : this(name, sequence, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Sequence - /// Flags - public ParamDefUser(UTF8String name, ushort sequence, ParamAttributes flags) { - this.name = name; - this.sequence = sequence; - attributes = (int)flags; - } - } - - /// - /// Created from a row in the Param table - /// - sealed class ParamDefMD : ParamDef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - protected override MarshalType GetMarshalType_NoLock() => - readerModule.ReadMarshalType(Table.Param, origRid, GenericParamContext.Create(declaringMethod)); - - /// - protected override Constant GetConstant_NoLock() => - readerModule.ResolveConstant(readerModule.Metadata.GetConstantRid(Table.Param, origRid)); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.Param, 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), GenericParamContext.Create(declaringMethod), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this Param row - /// Row ID - /// If is null - /// If is invalid - public ParamDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.ParamTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Param rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadParamRow(origRid, out var row); - Debug.Assert(b); - attributes = row.Flags; - sequence = row.Sequence; - name = readerModule.StringsStream.ReadNoNull(row.Name); - declaringMethod = readerModule.GetOwner(this); - } - - internal ParamDefMD InitializeAll() { - MemberMDInitializer.Initialize(DeclaringMethod); - MemberMDInitializer.Initialize(Attributes); - MemberMDInitializer.Initialize(Sequence); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(MarshalType); - MemberMDInitializer.Initialize(Constant); - MemberMDInitializer.Initialize(CustomAttributes); - return this; - } - } -} diff --git a/Plugins/dnlib/DotNet/ParameterList.cs b/Plugins/dnlib/DotNet/ParameterList.cs deleted file mode 100644 index 080de79..0000000 --- a/Plugins/dnlib/DotNet/ParameterList.cs +++ /dev/null @@ -1,525 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.Threading; -using dnlib.Utils; - -namespace dnlib.DotNet { - /// - /// A list of all method parameters - /// - [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(ParameterList_CollectionDebugView))] - public sealed class ParameterList : IList { - readonly MethodDef method; - readonly List parameters; - readonly Parameter hiddenThisParameter; - ParamDef hiddenThisParamDef; - readonly Parameter returnParameter; - int methodSigIndexBase; -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// Gets the owner method - /// - public MethodDef Method => method; - - /// - /// Gets the number of parameters, including a possible hidden 'this' parameter - /// - public int Count { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return parameters.Count; -#if THREAD_SAFE - } - finally { theLock.ExitReadLock(); } -#endif - } - } - - /// - /// Gets the index of the first parameter that is present in the method signature. - /// If this is a static method, the value is 0, else it's an instance method so the - /// index is 1 since the first parameter is the hidden 'this' parameter. - /// - public int MethodSigIndexBase { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return methodSigIndexBase == 1 ? 1 : 0; -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - } - - /// - /// Gets the N'th parameter - /// - /// The parameter index - public Parameter this[int index] { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return parameters[index]; -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - set => throw new NotSupportedException(); - } - - /// - /// Gets the method return parameter - /// - public Parameter ReturnParameter { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return returnParameter; -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - } - - /// - /// Constructor - /// - /// The method with all parameters - /// 's declaring type - public ParameterList(MethodDef method, TypeDef declaringType) { - this.method = method; - 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(); - } - - /// - /// Should be called when the method's declaring type has changed - /// - /// Method declaring type - internal void UpdateThisParameterType(TypeDef methodDeclaringType) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (methodDeclaringType is null) - hiddenThisParameter.Type = null; - 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 - } - - /// - /// Should be called when the method sig has changed - /// - public void UpdateParameterTypes() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - var sig = method.MethodSig; - if (sig is null) { - methodSigIndexBase = -1; - parameters.Clear(); - return; - } - if (UpdateThisParameter_NoLock(sig)) - parameters.Clear(); - returnParameter.Type = sig.RetType; - ResizeParameters_NoLock(sig.Params.Count + methodSigIndexBase); - if (methodSigIndexBase > 0) - parameters[0] = hiddenThisParameter; - for (int i = 0; i < sig.Params.Count; i++) - parameters[i + methodSigIndexBase].Type = sig.Params[i]; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - bool UpdateThisParameter_NoLock(MethodSig methodSig) { - int newIndex; - if (methodSig is null) - newIndex = -1; - else - newIndex = methodSig.ImplicitThis ? 1 : 0; - if (methodSigIndexBase == newIndex) - return false; - methodSigIndexBase = newIndex; - return true; - } - - void ResizeParameters_NoLock(int length) { - if (parameters.Count == length) - return; - if (parameters.Count < length) { - for (int i = parameters.Count; i < length; i++) - parameters.Add(new Parameter(this, i, i - methodSigIndexBase)); - } - else { - while (parameters.Count > length) - parameters.RemoveAt(parameters.Count - 1); - } - } - - internal ParamDef FindParamDef(Parameter param) { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return FindParamDef_NoLock(param); -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - - ParamDef FindParamDef_NoLock(Parameter param) { - int seq; - if (param.IsReturnTypeParameter) - seq = 0; - else if (param.IsNormalMethodParameter) - seq = param.MethodSigIndex + 1; - else - return hiddenThisParamDef; - - var paramDefs = method.ParamDefs; - int count = paramDefs.Count; - for (int i = 0; i < count; i++) { - var paramDef = paramDefs[i]; - if (paramDef is not null && paramDef.Sequence == seq) - return paramDef; - } - return null; - } - - internal void TypeUpdated(Parameter param) { - var sig = method.MethodSig; - if (sig is null) - return; - int index = param.MethodSigIndex; - if (index == Parameter.RETURN_TYPE_METHOD_SIG_INDEX) - sig.RetType = param.Type; - else if (index >= 0) - sig.Params[index] = param.Type; - } - - internal void CreateParamDef(Parameter param) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - var paramDef = FindParamDef_NoLock(param); - if (paramDef is not null) - return; - if (param.IsHiddenThisParameter) { - hiddenThisParamDef = UpdateRowId_NoLock(new ParamDefUser(UTF8String.Empty, ushort.MaxValue, 0)); - return; - } - int seq = param.IsReturnTypeParameter ? 0 : param.MethodSigIndex + 1; - paramDef = UpdateRowId_NoLock(new ParamDefUser(UTF8String.Empty, (ushort)seq, 0)); - method.ParamDefs.Add(paramDef); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - ParamDef UpdateRowId_NoLock(ParamDef pd) { - var dt = method.DeclaringType; - if (dt is null) - return pd; - var module = dt.Module; - if (module is null) - return pd; - return module.UpdateRowId(pd); - } - - /// - public int IndexOf(Parameter item) { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return parameters.IndexOf(item); -#if THREAD_SAFE - } - finally { theLock.ExitReadLock(); } -#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(); - - bool ICollection.Contains(Parameter item) { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return parameters.Contains(item); -#if THREAD_SAFE - } - finally { theLock.ExitReadLock(); } -#endif - } - - void ICollection.CopyTo(Parameter[] array, int arrayIndex) { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - parameters.CopyTo(array, arrayIndex); -#if THREAD_SAFE - } - finally { theLock.ExitReadLock(); } -#endif - } - - bool ICollection.IsReadOnly => true; - bool ICollection.Remove(Parameter item) => throw new NotSupportedException(); - - /// - /// Enumerator - /// - public struct Enumerator : IEnumerator { - readonly ParameterList list; - List.Enumerator listEnumerator; - Parameter current; - - internal Enumerator(ParameterList list) { - this.list = list; - current = default; -#if THREAD_SAFE - list.theLock.EnterReadLock(); try { -#endif - listEnumerator = list.parameters.GetEnumerator(); -#if THREAD_SAFE - } finally { list.theLock.ExitReadLock(); } -#endif - } - - /// - /// Gets the current value - /// - public Parameter Current => current; - Parameter IEnumerator.Current => current; - object System.Collections.IEnumerator.Current => current; - - /// - /// Moves to the next element in the collection - /// - /// - public bool MoveNext() { -#if THREAD_SAFE - list.theLock.EnterWriteLock(); try { -#endif - var res = listEnumerator.MoveNext(); - current = listEnumerator.Current; - return res; -#if THREAD_SAFE - } finally { list.theLock.ExitWriteLock(); } -#endif - } - - /// - /// Disposes the enumerator - /// - public void Dispose() => listEnumerator.Dispose(); - - void System.Collections.IEnumerator.Reset() => throw new NotSupportedException(); - } - - /// - /// Gets the list enumerator - /// - /// - public Enumerator GetEnumerator() => new Enumerator(this); - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - } - - /// - /// A method parameter - /// - public sealed class Parameter : IVariable { - readonly ParameterList parameterList; - TypeSig typeSig; - readonly int paramIndex; - readonly int methodSigIndex; - - /// - /// The hidden 'this' parameter's - /// - public const int HIDDEN_THIS_METHOD_SIG_INDEX = -2; - - /// - /// The return type parameter's - /// - public const int RETURN_TYPE_METHOD_SIG_INDEX = -1; - - /// - /// Gets the parameter index. If the method has a hidden 'this' parameter, that parameter - /// 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 => paramIndex; - - /// - /// Gets the index of the parameter in the method signature. See also - /// and - /// - 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 => methodSigIndex >= 0; - - /// - /// true if it's the hidden 'this' parameter - /// - public bool IsHiddenThisParameter => methodSigIndex == HIDDEN_THIS_METHOD_SIG_INDEX; - - /// - /// true if it's the method return type parameter - /// - public bool IsReturnTypeParameter => methodSigIndex == RETURN_TYPE_METHOD_SIG_INDEX; - - /// - /// Gets the parameter type - /// - public TypeSig Type { - get => typeSig; - set { - typeSig = value; - if (parameterList is not null) - parameterList.TypeUpdated(this); - } - } - - /// - /// Gets the owner method - /// - public MethodDef Method => parameterList?.Method; - - /// - /// Gets the or null if not present - /// - public ParamDef ParamDef => parameterList?.FindParamDef(this); - - /// - /// true if it has a - /// - public bool HasParamDef => ParamDef is not null; - - /// - /// Gets the name from . If is null, - /// an empty string is returned. - /// - public string Name { - get { - var paramDef = ParamDef; - return paramDef is null ? string.Empty : UTF8String.ToSystemStringOrEmpty(paramDef.Name); - } - set { - var paramDef = ParamDef; - if (paramDef is not null) - paramDef.Name = value; - } - } - - /// - /// Constructor - /// - /// Parameter index - public Parameter(int paramIndex) { - this.paramIndex = paramIndex; - methodSigIndex = paramIndex; - } - - /// - /// Constructor - /// - /// Parameter index - /// Parameter type - public Parameter(int paramIndex, TypeSig type) { - this.paramIndex = paramIndex; - methodSigIndex = paramIndex; - typeSig = type; - } - - /// - /// Constructor - /// - /// Parameter index (0 is hidden this param if it exists) - /// Index in method signature - public Parameter(int paramIndex, int methodSigIndex) { - this.paramIndex = paramIndex; - this.methodSigIndex = methodSigIndex; - } - - /// - /// Constructor - /// - /// Parameter index (0 is hidden this param if it exists) - /// Index in method signature - /// Parameter type - public Parameter(int paramIndex, int methodSigIndex, TypeSig type) { - this.paramIndex = paramIndex; - this.methodSigIndex = methodSigIndex; - typeSig = type; - } - - internal Parameter(ParameterList parameterList, int paramIndex, int methodSigIndex) { - this.parameterList = parameterList; - this.paramIndex = paramIndex; - this.methodSigIndex = methodSigIndex; - } - - /// - /// Creates a if it doesn't already exist - /// - public void CreateParamDef() { - if (parameterList is not null) - parameterList.CreateParamDef(this); - } - - /// - public override string ToString() { - var name = Name; - if (string.IsNullOrEmpty(name)) { - if (IsReturnTypeParameter) - return "RET_PARAM"; - return $"A_{paramIndex}"; - } - return name; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/CustomDebugInfoGuids.cs b/Plugins/dnlib/DotNet/Pdb/CustomDebugInfoGuids.cs deleted file mode 100644 index 71342b5..0000000 --- a/Plugins/dnlib/DotNet/Pdb/CustomDebugInfoGuids.cs +++ /dev/null @@ -1,28 +0,0 @@ -// 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"); - 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"); - 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/Plugins/dnlib/DotNet/Pdb/DataReaderFactoryUtils.cs b/Plugins/dnlib/DotNet/Pdb/DataReaderFactoryUtils.cs deleted file mode 100644 index 8009714..0000000 --- a/Plugins/dnlib/DotNet/Pdb/DataReaderFactoryUtils.cs +++ /dev/null @@ -1,26 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Security; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb { - static class DataReaderFactoryUtils { - public static DataReaderFactory TryCreateDataReaderFactory(string filename) { - try { - if (!File.Exists(filename)) - return null; - // Don't use memory mapped I/O - return ByteArrayDataReaderFactory.Create(File.ReadAllBytes(filename), filename); - } - catch (IOException) { - } - catch (UnauthorizedAccessException) { - } - catch (SecurityException) { - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/ComInterfaces.cs b/Plugins/dnlib/DotNet/Pdb/Dss/ComInterfaces.cs deleted file mode 100644 index a57c846..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/ComInterfaces.cs +++ /dev/null @@ -1,503 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; - -// 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("997DD0CC-A76F-4c82-8D79-EA87559D27AD"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedSourceServerModule { - [PreserveSig] - int GetSourceServerData(out int pDataByteCount, out IntPtr ppData); - } - - [ComVisible(true), - ComImport, - Guid("B4CE6286-2A6B-3712-A3B7-1EE1DAD467B5"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedReader { - void GetDocument([In, MarshalAs(UnmanagedType.LPWStr)] string url, [In] Guid language, [In] Guid languageVendor, [In] Guid documentType, [Out] out ISymUnmanagedDocument pRetVal); - 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); - 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); - 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); - [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); - void GetMethodsFromDocumentPosition([In] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cMethod, [Out] out uint pcMethod, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] ISymUnmanagedMethod[] pRetVal); - void GetDocumentVersion([In] ISymUnmanagedDocument pDoc, [Out] out int version, [Out] out bool pbCurrent); - 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); - [PreserveSig] - int GetSourceServerData(out IntPtr data, out int 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"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedDocument { - void GetURL([In] uint cchUrl, [Out] out uint pcchUrl, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] szUrl); - void GetDocumentType([Out] out Guid pRetVal); - void GetLanguage([Out] out Guid pRetVal); - void GetLanguageVendor([Out] out Guid pRetVal); - void GetCheckSumAlgorithmId([Out] out Guid pRetVal); - 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); - [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), - ComImport, - Guid("B62B923C-B500-3158-A543-24F307A8B7E1"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedMethod { - void GetToken([Out] out uint pToken); - void GetSequencePointCount([Out] out uint pRetVal); - void GetRootScope([Out] out ISymUnmanagedScope pRetVal); - void GetScopeFromOffset([In] uint offset, [Out] out ISymUnmanagedScope pRetVal); - void GetOffset([In] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [Out] out uint pRetVal); - void GetRanges([In] ISymUnmanagedDocument document, [In] uint line, [In] uint column, [In] uint cRanges, [Out] out uint pcRanges, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] int[] ranges); - void GetParameters([In] uint cParams, [Out] out uint pcParams, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] parameters); - void GetNamespace([Out] out ISymUnmanagedNamespace pRetVal); - void GetSourceStartEnd([In] ISymUnmanagedDocument[/*2*/] docs, [In] int[/*2*/] lines, [In] int[/*2*/] columns, [Out] out bool pRetVal); - 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"), - 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"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedVariable { - void GetName([In] uint cchName, [Out] out uint pcchName, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] szName); - void GetAttributes([Out] out uint pRetVal); - void GetSignature([In] uint cSig, [Out] out uint pcSig, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] byte[] sig); - void GetAddressKind([Out] out uint pRetVal); - void GetAddressField1([Out] out uint pRetVal); - void GetAddressField2([Out] out uint pRetVal); - void GetAddressField3([Out] out uint pRetVal); - void GetStartOffset([Out] out uint pRetVal); - void GetEndOffset([Out] out uint pRetVal); - } - - [ComVisible(true), - ComImport, - Guid("0DFF7289-54F8-11D3-BD28-0000F80849BD"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedNamespace { - void GetName([In] uint cchName, [Out] out uint pcchName, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] char[] szName); - void GetNamespaces([In] uint cNameSpaces, [Out] out uint pcNameSpaces, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedNamespace[] namespaces); - void GetVariables([In] uint cVars, [Out] out uint pcVars, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 0)] ISymUnmanagedVariable[] pVars); - } - - [ComVisible(true), - ComImport, - Guid("68005D0F-B8E0-3B01-84D5-A11A94154942"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedScope { - 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); - } - - [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"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - unsafe interface IMetaDataImport { - void CloseEnum(IntPtr hEnum); - void CountEnum(IntPtr hEnum, ref uint pulCount); - void ResetEnum(IntPtr hEnum, uint ulPos); - void EnumTypeDefs(IntPtr phEnum, uint[] rTypeDefs, uint cMax, out uint pcTypeDefs); - void EnumInterfaceImpls(ref IntPtr phEnum, uint td, uint[] rImpls, uint cMax, ref uint pcImpls); - void EnumTypeRefs(ref IntPtr phEnum, uint[] rTypeRefs, uint cMax, ref uint pcTypeRefs); - 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); - 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] 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); - void EnumMethods([In, Out] ref IntPtr phEnum, [In] uint cl, [Out] uint[] rMethods, [In] uint cMax, [Out] out uint pcTokens); - void EnumMethodsWithName([In, Out] ref IntPtr phEnum, [In] uint cl, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, uint[] rMethods, [In] uint cMax, [Out] out uint pcTokens); - void EnumFields([In, Out] ref IntPtr phEnum, [In] uint cl, [Out] uint[] rFields, [In] uint cMax, [Out] out uint pcTokens); - void EnumFieldsWithName([In, Out] ref IntPtr phEnum, [In] uint cl, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] uint[] rFields, [In] uint cMax, [Out] out uint pcTokens); - void EnumParams([In, Out] ref IntPtr phEnum, [In] uint mb, [Out] uint[] rParams, [In] uint cMax, [Out] out uint pcTokens); - void EnumMemberRefs([In, Out] ref IntPtr phEnum, [In] uint tkParent, [Out] uint[] rMemberRefs, [In] uint cMax, [Out] out uint pcTokens); - void EnumMethodImpls([In, Out] ref IntPtr phEnum, [In] uint td, [Out] uint[] rMethodBody, [Out] uint[] rMethodDecl, [In] uint cMax, [Out] out uint pcTokens); - void EnumPermissionSets([In, Out] ref IntPtr phEnum, [In] uint tk, [In] uint dwActions, [Out] uint[] rPermission, [In] uint cMax, [Out] out uint pcTokens); - void FindMember([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [Out] out uint pmb); - 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); - 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); - void GetEventProps([In] uint ev, [Out] out uint pClass, [Out] [MarshalAs(UnmanagedType.LPWStr)] string szEvent, [In] uint cchEvent, [Out] out uint pchEvent, [Out] out uint pdwEventFlags, [Out] out uint ptkEventType, [Out] out uint pmdAddOn, [Out] out uint pmdRemoveOn, [Out] out uint pmdFire, [In, Out] uint[] rmdOtherMethod, [In] uint cMax, [Out] out uint pcOtherMethod); - void EnumMethodSemantics([In, Out] ref IntPtr phEnum, [In] uint mb, [In, Out] uint[] rEventProp, [In] uint cMax, [Out] out uint pcEventProp); - void GetMethodSemantics([In] uint mb, [In] uint tkEventProp, [Out] out uint pdwSemanticsFlags); - void GetClassLayout([In] uint td, [Out] out uint pdwPackSize, [Out] out IntPtr rFieldOffset, [In] uint cMax, [Out] out uint pcFieldOffset, [Out] out uint pulClassSize); - 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] 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); - void GetNameFromToken([In] uint tk, [Out] out IntPtr pszUtf8NamePtr); - void EnumUnresolvedMethods([In, Out] ref IntPtr phEnum, [Out] uint[] rMethods, [In] uint cMax, [Out] out uint pcTokens); - void GetUserString([In] uint stk, [Out] IntPtr szString, [In] uint cchString, [Out] out uint pchString); - void GetPinvokeMap([In] uint tk, [Out] out uint pdwMappingFlags, [Out] IntPtr szImportName, [In] uint cchImportName, [Out] out uint pchImportName, [Out] out uint pmrImportDLL); - void EnumSignatures([In, Out] ref IntPtr phEnum, [Out] uint[] rSignatures, [In] uint cmax, [Out] out uint pcSignatures); - void EnumTypeSpecs([In, Out] ref IntPtr phEnum, [Out] uint[] rTypeSpecs, [In] uint cmax, [Out] out uint pcTypeSpecs); - void EnumUserStrings([In, Out] ref IntPtr phEnum, [Out] uint[] rStrings, [In] uint cmax, [Out] out uint pcStrings); - void GetParamForMethodIndex([In] uint md, [In] uint ulParamSeq, [Out] out uint ppd); - void EnumCustomAttributes([In, Out] IntPtr phEnum, [In] uint tk, [In] uint tkType, [Out] uint[] rCustomAttributes, [In] uint cMax, [Out] out uint pcCustomAttributes); - void GetCustomAttributeProps([In] uint cv, [Out] out uint ptkObj, [Out] out uint ptkType, [Out] out IntPtr ppBlob, [Out] out uint pcbSize); - void FindTypeRef([In] uint tkResolutionScope, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] out uint ptr); - void GetMemberProps(uint mb, out uint pClass, IntPtr szMember, uint cchMember, out uint pchMember, out uint pdwAttr, [Out] out IntPtr ppvSigBlob, [Out] out uint pcbSigBlob, [Out] out uint pulCodeRVA, [Out] out uint pdwImplFlags, [Out] out uint pdwCPlusTypeFlag, [Out] out IntPtr ppValue, [Out] out uint pcchValue); - void GetFieldProps(uint mb, out uint pClass, IntPtr szField, uint cchField, out uint pchField, out uint pdwAttr, [Out] out IntPtr ppvSigBlob, [Out] out uint pcbSigBlob, [Out] out uint pdwCPlusTypeFlag, [Out] out IntPtr ppValue, [Out] out uint pcchValue); - void GetPropertyProps([In] uint prop, [Out] out uint pClass, [Out] IntPtr szProperty, [In] uint cchProperty, [Out] out uint pchProperty, [Out] out uint pdwPropFlags, [Out] out IntPtr ppvSig, [Out] out uint pbSig, [Out] out uint pdwCPlusTypeFlag, [Out] out IntPtr ppDefaultValue, [Out] out uint pcchDefaultValue, [Out] out uint pmdSetter, [Out] out uint pmdGetter, [In, Out] uint[] rmdOtherMethod, [In] uint cMax, [Out] out uint pcOtherMethod); - 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); - 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); - } - - [ComVisible(true), - ComImport, - Guid("BA3FEE4C-ECB9-4E41-83B7-183FA41CD859"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface IMetaDataEmit { - void SetModuleProps([In] [MarshalAs(UnmanagedType.LPWStr)] string szName); - void Save([In] [MarshalAs(UnmanagedType.LPWStr)] string szFile, [In] uint dwSaveFlags); - void SaveToStream([In] IStream pIStream, [In] uint dwSaveFlags); - void GetSaveSize([In] int fSave, [Out] out uint pdwSaveSize); - void DefineTypeDef([In] [MarshalAs(UnmanagedType.LPWStr)] string szTypeDef, [In] uint dwTypeDefFlags, [In] uint tkExtends, [In] uint[] rtkImplements, [Out] out uint ptd); - void DefineNestedType([In] [MarshalAs(UnmanagedType.LPWStr)] string szTypeDef, [In] uint dwTypeDefFlags, [In] uint tkExtends, [In] uint[] rtkImplements, [In] uint tdEncloser, [Out] out uint ptd); - void SetHandler([In, MarshalAs(UnmanagedType.IUnknown)] object pUnk); - void DefineMethod(uint td, [MarshalAs(UnmanagedType.LPWStr)] string szName, uint dwMethodFlags, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, uint ulCodeRVA, uint dwImplFlags, out uint pmd); - void DefineMethodImpl([In] uint td, [In] uint tkBody, [In] uint tkDecl); - void DefineTypeRefByName([In] uint tkResolutionScope, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] out uint ptr); - void DefineImportType([In] IntPtr pAssemImport, [In] IntPtr pbHashValue, [In] uint cbHashValue, [In] IMetaDataImport pImport, [In] uint tdImport, [In] IntPtr pAssemEmit, [Out] out uint ptr); - void DefineMemberRef([In] uint tkImport, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [Out] out uint pmr); - void DefineImportMember([In] IntPtr pAssemImport, [In] IntPtr pbHashValue, [In] uint cbHashValue, [In] IMetaDataImport pImport, [In] uint mbMember, [In] IntPtr pAssemEmit, [In] uint tkParent, [Out] out uint pmr); - void DefineEvent([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szEvent, [In] uint dwEventFlags, [In] uint tkEventType, [In] uint mdAddOn, [In] uint mdRemoveOn, [In] uint mdFire, [In] uint[] rmdOtherMethods, [Out] out uint pmdEvent); - void SetClassLayout([In] uint td, [In] uint dwPackSize, [In] IntPtr rFieldOffsets, [In] uint ulClassSize); - void DeleteClassLayout([In] uint td); - void SetFieldMarshal([In] uint tk, [In] IntPtr pvNativeType, [In] uint cbNativeType); - void DeleteFieldMarshal([In] uint tk); - void DefinePermissionSet([In] uint tk, [In] uint dwAction, [In] IntPtr pvPermission, [In] uint cbPermission, [Out] out uint ppm); - void SetRVA([In] uint md, [In] uint ulRVA); - void GetTokenFromSig([In] IntPtr pvSig, [In] uint cbSig, [Out] out uint pmsig); - void DefineModuleRef([In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [Out] out uint pmur); - void SetParent([In] uint mr, [In] uint tk); - void GetTokenFromTypeSpec([In] IntPtr pvSig, [In] uint cbSig, [Out] out uint ptypespec); - void SaveToMemory([Out] out IntPtr pbData, [In] uint cbData); - void DefineUserString([In] [MarshalAs(UnmanagedType.LPWStr)] string szString, [In] uint cchString, [Out] out uint pstk); - void DeleteToken([In] uint tkObj); - void SetMethodProps([In] uint md, [In] uint dwMethodFlags, [In] uint ulCodeRVA, [In] uint dwImplFlags); - void SetTypeDefProps([In] uint td, [In] uint dwTypeDefFlags, [In] uint tkExtends, [In] uint[] rtkImplements); - void SetEventProps([In] uint ev, [In] uint dwEventFlags, [In] uint tkEventType, [In] uint mdAddOn, [In] uint mdRemoveOn, [In] uint mdFire, [In] uint[] rmdOtherMethods); - void SetPermissionSetProps([In] uint tk, [In] uint dwAction, [In] IntPtr pvPermission, [In] uint cbPermission, [Out] out uint ppm); - void DefinePinvokeMap([In] uint tk, [In] uint dwMappingFlags, [In] [MarshalAs(UnmanagedType.LPWStr)] string szImportName, [In] uint mrImportDLL); - void SetPinvokeMap([In] uint tk, [In] uint dwMappingFlags, [In] [MarshalAs(UnmanagedType.LPWStr)] string szImportName, [In] uint mrImportDLL); - void DeletePinvokeMap([In] uint tk); - void DefineCustomAttribute([In] uint tkOwner, [In] uint tkCtor, [In] IntPtr pCustomAttribute, [In] uint cbCustomAttribute, [Out] out uint pcv); - void SetCustomAttributeValue([In] uint pcv, [In] IntPtr pCustomAttribute, [In] uint cbCustomAttribute); - void DefineField(uint td, [MarshalAs(UnmanagedType.LPWStr)] string szName, uint dwFieldFlags, [In] IntPtr pvSigBlob, [In] uint cbSigBlob, [In] uint dwCPlusTypeFlag, [In] IntPtr pValue, [In] uint cchValue, [Out] out uint pmd); - void DefineProperty([In] uint td, [In] [MarshalAs(UnmanagedType.LPWStr)] string szProperty, [In] uint dwPropFlags, [In] IntPtr pvSig, [In] uint cbSig, [In] uint dwCPlusTypeFlag, [In] IntPtr pValue, [In] uint cchValue, [In] uint mdSetter, [In] uint mdGetter, [In] uint[] rmdOtherMethods, [Out] out uint pmdProp); - void DefineParam([In] uint md, [In] uint ulParamSeq, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] uint dwParamFlags, [In] uint dwCPlusTypeFlag, [In] IntPtr pValue, [In] uint cchValue, [Out] out uint ppd); - void SetFieldProps([In] uint fd, [In] uint dwFieldFlags, [In] uint dwCPlusTypeFlag, [In] IntPtr pValue, [In] uint cchValue); - void SetPropertyProps([In] uint pr, [In] uint dwPropFlags, [In] uint dwCPlusTypeFlag, [In] IntPtr pValue, [In] uint cchValue, [In] uint mdSetter, [In] uint mdGetter, [In] uint[] rmdOtherMethods); - void SetParamProps([In] uint pd, [In] [MarshalAs(UnmanagedType.LPWStr)] string szName, [In] uint dwParamFlags, [In] uint dwCPlusTypeFlag, [Out] IntPtr pValue, [In] uint cchValue); - void DefineSecurityAttributeSet([In] uint tkObj, [In] IntPtr rSecAttrs, [In] uint cSecAttrs, [Out] out uint pulErrorAttr); - void ApplyEditAndContinue([In, MarshalAs(UnmanagedType.IUnknown)] object pImport); - void TranslateSigWithScope([In] IntPtr pAssemImport, [In] IntPtr pbHashValue, [In] uint cbHashValue, [In] IMetaDataImport import, [In] IntPtr pbSigBlob, [In] uint cbSigBlob, [In] IntPtr pAssemEmit, [In] IMetaDataEmit emit, [Out] IntPtr pvTranslatedSig, uint cbTranslatedSigMax, [Out] out uint pcbTranslatedSig); - void SetMethodImplFlags([In] uint md, uint dwImplFlags); - void SetFieldRVA([In] uint fd, [In] uint ulRVA); - void Merge([In] IMetaDataImport pImport, [In] IntPtr pHostMapToken, [In, MarshalAs(UnmanagedType.IUnknown)] object pHandler); - void MergeEnd(); - } - - [ComVisible(true), - ComImport, - Guid("ED14AA72-78E2-4884-84E2-334293AE5214"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedWriter { - void DefineDocument([In] [MarshalAs(UnmanagedType.LPWStr)] string url, [In] ref Guid language, [In] ref Guid languageVendor, [In] ref Guid documentType, [Out] out ISymUnmanagedDocumentWriter pRetVal); - void SetUserEntryPoint([In] uint entryMethod); - void OpenMethod([In] uint method); - void CloseMethod(); - void OpenScope([In] uint startOffset, [Out] out uint pRetVal); - void CloseScope([In] uint endOffset); - void SetScopeRange([In] uint scopeID, [In] uint startOffset, [In] uint endOffset); - void DefineLocalVariable([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); - void DefineParameter([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint sequence, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void DefineField([In] uint parent, [In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void DefineGlobalVariable([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void Close(); - void SetSymAttribute([In] uint parent, [In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint cData, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] data); - void OpenNamespace([In] [MarshalAs(UnmanagedType.LPWStr)] string name); - void CloseNamespace(); - void UsingNamespace([In] [MarshalAs(UnmanagedType.LPWStr)] string fullName); - void SetMethodSourceRange([In] ISymUnmanagedDocumentWriter startDoc, [In] uint startLine, [In] uint startColumn, [In] ISymUnmanagedDocumentWriter endDoc, [In] uint endLine, [In] uint endColumn); - void Initialize([In] IntPtr emitter, [In] [MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream, [In] bool fFullBuild); - void GetDebugInfo([Out] out IMAGE_DEBUG_DIRECTORY pIDD, [In] uint cData, [Out] out uint pcData, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data); - void DefineSequencePoints([In] ISymUnmanagedDocumentWriter document, [In] uint spCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] offsets, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] lines, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] columns, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endLines, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endColumns); - void RemapToken([In] uint oldToken, [In] uint newToken); - void Initialize2([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] [MarshalAs(UnmanagedType.LPWStr)] string tempfilename, [In] IStream pIStream, [In] bool fFullBuild, [In] [MarshalAs(UnmanagedType.LPWStr)] string finalfilename); - void DefineConstant([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] object value, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature); - void Abort(); - } - - [ComVisible(true), - ComImport, - Guid("0B97726E-9E6D-4F05-9A26-424022093CAA"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - interface ISymUnmanagedWriter2 { - void DefineDocument([In] [MarshalAs(UnmanagedType.LPWStr)] string url, [In] ref Guid language, [In] ref Guid languageVendor, [In] ref Guid documentType, [Out] out ISymUnmanagedDocumentWriter pRetVal); - void SetUserEntryPoint([In] uint entryMethod); - void OpenMethod([In] uint method); - void CloseMethod(); - void OpenScope([In] uint startOffset, [Out] out uint pRetVal); - void CloseScope([In] uint endOffset); - void SetScopeRange([In] uint scopeID, [In] uint startOffset, [In] uint endOffset); - void DefineLocalVariable([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); - void DefineParameter([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint sequence, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void DefineField([In] uint parent, [In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 3)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void DefineGlobalVariable([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3); - void Close(); - void SetSymAttribute([In] uint parent, [In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint cData, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] data); - void OpenNamespace([In] [MarshalAs(UnmanagedType.LPWStr)] string name); - void CloseNamespace(); - void UsingNamespace([In] [MarshalAs(UnmanagedType.LPWStr)] string fullName); - void SetMethodSourceRange([In] ISymUnmanagedDocumentWriter startDoc, [In] uint startLine, [In] uint startColumn, [In] ISymUnmanagedDocumentWriter endDoc, [In] uint endLine, [In] uint endColumn); - void Initialize([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] [MarshalAs(UnmanagedType.LPWStr)] string filename, [In] IStream pIStream, [In] bool fFullBuild); - void GetDebugInfo([Out] out IMAGE_DEBUG_DIRECTORY pIDD, [In] uint cData, [Out] out uint pcData, [Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] byte[] data); - void DefineSequencePoints([In] ISymUnmanagedDocumentWriter document, [In] uint spCount, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] offsets, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] lines, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] columns, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endLines, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)] int[] endColumns); - void RemapToken([In] uint oldToken, [In] uint newToken); - void Initialize2([In, MarshalAs(UnmanagedType.IUnknown)] object emitter, [In] [MarshalAs(UnmanagedType.LPWStr)] string tempfilename, [In] IStream pIStream, [In] bool fFullBuild, [In] [MarshalAs(UnmanagedType.LPWStr)] string finalfilename); - void DefineConstant([In] [MarshalAs(UnmanagedType.LPWStr)] string name, [In] object value, [In] uint cSig, [In, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] byte[] signature); - void Abort(); - void DefineLocalVariable2([In, MarshalAs(UnmanagedType.LPWStr)] string name, [In] uint attributes, [In] uint sigToken, [In] uint addrKind, [In] uint addr1, [In] uint addr2, [In] uint addr3, [In] uint startOffset, [In] uint endOffset); - 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); - } - - [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"), - InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] - 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); - } - - [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/Plugins/dnlib/DotNet/Pdb/Dss/DataReaderIStream.cs b/Plugins/dnlib/DotNet/Pdb/Dss/DataReaderIStream.cs deleted file mode 100644 index 1733c53..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/DataReaderIStream.cs +++ /dev/null @@ -1,130 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class DataReaderIStream : IStream, IDisposable { - readonly DataReaderFactory dataReaderFactory; - DataReader reader; - readonly string name; - - const int STG_E_INVALIDFUNCTION = unchecked((int)0x80030001); - const int STG_E_CANTSAVE = unchecked((int)0x80030103); - - public DataReaderIStream(DataReaderFactory dataReaderFactory) - : this(dataReaderFactory, dataReaderFactory.CreateReader(), string.Empty) { - } - - DataReaderIStream(DataReaderFactory dataReaderFactory, DataReader reader, string name) { - this.dataReaderFactory = dataReaderFactory ?? throw new ArgumentNullException(nameof(dataReaderFactory)); - this.reader = reader; - 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; - else if (cb < 0) - cb = 0; - int sizeToRead = (int)cb; - - if ((ulong)reader.Position + (uint)sizeToRead > reader.Length) - sizeToRead = (int)(reader.Length - Math.Min(reader.Position, reader.Length)); - - var buffer = new byte[sizeToRead]; - Read(buffer, sizeToRead, pcbRead); - if (pcbRead != IntPtr.Zero) - Marshal.WriteInt64(pcbRead, Marshal.ReadInt32(pcbRead)); - pstm.Write(buffer, buffer.Length, pcbWritten); - if (pcbWritten != IntPtr.Zero) - 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; - - cb = (int)Math.Min(reader.BytesLeft, (uint)cb); - reader.ReadBytes(pv, 0, cb); - - if (pcbRead != IntPtr.Zero) - Marshal.WriteInt32(pcbRead, cb); - } - - public void Revert() { - } - - enum STREAM_SEEK { - SET = 0, - CUR = 1, - END = 2, - } - - public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { - switch ((STREAM_SEEK)dwOrigin) { - case STREAM_SEEK.SET: - reader.Position = (uint)dlibMove; - break; - - case STREAM_SEEK.CUR: - reader.Position = (uint)(reader.Position + dlibMove); - break; - - case STREAM_SEEK.END: - reader.Position = (uint)(reader.Length + dlibMove); - break; - } - - if (plibNewPosition != IntPtr.Zero) - Marshal.WriteInt64(plibNewPosition, reader.Position); - } - - public void SetSize(long libNewSize) => Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - - enum STATFLAG { - DEFAULT = 0, - NONAME = 1, - NOOPEN = 2, - } - - enum STGTY { - STORAGE = 1, - STREAM = 2, - LOCKBYTES = 3, - PROPERTY = 4, - } - - public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag) { - var s = new System.Runtime.InteropServices.ComTypes.STATSTG(); - - // s.atime = ???; - s.cbSize = reader.Length; - s.clsid = Guid.Empty; - // s.ctime = ???; - s.grfLocksSupported = 0; - s.grfMode = 0; - s.grfStateBits = 0; - // s.mtime = ???; - if ((grfStatFlag & (int)STATFLAG.NONAME) == 0) - s.pwcsName = name; - s.reserved = 0; - s.type = (int)STGTY.STREAM; - - 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() { } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/MDEmitter.cs b/Plugins/dnlib/DotNet/Pdb/Dss/MDEmitter.cs deleted file mode 100644 index 5b38003..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/MDEmitter.cs +++ /dev/null @@ -1,143 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Runtime.InteropServices.ComTypes; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet.Pdb.Dss { - sealed unsafe class MDEmitter : MetaDataImport, IMetaDataEmit { - readonly Metadata metadata; - readonly Dictionary tokenToTypeDef; - readonly Dictionary tokenToMethodDef; - - public MDEmitter(Metadata metadata) { - this.metadata = metadata; - - // We could get these from the metadata tables but it's just easier to get name, - // declaring type etc using TypeDef and MethodDef. - - tokenToTypeDef = new Dictionary(metadata.TablesHeap.TypeDefTable.Rows); - tokenToMethodDef = new Dictionary(metadata.TablesHeap.MethodTable.Rows); - foreach (var type in metadata.Module.GetTypes()) { - 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 is null) - continue; - tokenToMethodDef.Add(new MDToken(MD.Table.Method, metadata.GetRid(method)).Raw, method); - } - } - } - - 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]; - var row = metadata.TablesHeap.MethodTable[mb & 0x00FFFFFF]; - - if (pClass is not null) - *pClass = new MDToken(MD.Table.TypeDef, metadata.GetRid(method.DeclaringType)).Raw; - if (pdwAttr is not null) - *pdwAttr = row.Flags; - if (ppvSigBlob is not null) - *ppvSigBlob = IntPtr.Zero; - if (pcbSigBlob is not null) - *pcbSigBlob = 0; - if (pulCodeRVA is not null) - *pulCodeRVA = row.RVA; - 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 not null) { - for (int i = 0; i < len - 1; i++, szMethod++) - *szMethod = (ushort)name[i]; - if (len > 0) - *szMethod = 0; - } - if (pchMethod is not null) - *pchMethod = (uint)len; - } - - 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]; - var row = metadata.TablesHeap.TypeDefTable[td & 0x00FFFFFF]; - if (pdwTypeDefFlags is not null) - *pdwTypeDefFlags = row.Flags; - if (ptkExtends is not null) - *ptkExtends = row.Extends; - CopyTypeName(type.Namespace, type.Name, szTypeDef, cchTypeDef, pchTypeDef); - } - - public override void GetNestedClassProps(uint tdNestedClass, uint* ptdEnclosingClass) { - if ((tdNestedClass >> 24) != 0x02) - throw new ArgumentException(); - var type = tokenToTypeDef[tdNestedClass]; - var declType = type.DeclaringType; - if (ptdEnclosingClass is not null) { - if (declType is null) - *ptdEnclosingClass = 0; - else - *ptdEnclosingClass = new MDToken(MD.Table.TypeDef, metadata.GetRid(declType)).Raw; - } - } - - void IMetaDataEmit.GetTokenFromSig(IntPtr pvSig, uint cbSig, out uint pmsig) => pmsig = 0x11000000; - - // The rest of the methods aren't called - - 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.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/Plugins/dnlib/DotNet/Pdb/Dss/MetaDataImport.cs b/Plugins/dnlib/DotNet/Pdb/Dss/MetaDataImport.cs deleted file mode 100644 index da7f827..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/MetaDataImport.cs +++ /dev/null @@ -1,106 +0,0 @@ -// 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 is null) - typeName = string.Empty; - if (typeNamespace is null) - typeNamespace = string.Empty; - - if (destBuffer is not 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 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 not 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/Plugins/dnlib/DotNet/Pdb/Dss/ReaderMetaDataImport.cs b/Plugins/dnlib/DotNet/Pdb/Dss/ReaderMetaDataImport.cs deleted file mode 100644 index 910904d..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/ReaderMetaDataImport.cs +++ /dev/null @@ -1,85 +0,0 @@ -// 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 { - 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 is 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 is not null) - *ptkResolutionScope = row.ResolutionScope; - 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); - } - } - - 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 is not null) - *pdwTypeDefFlags = row.Flags; - if (ptkExtends is not null) - *ptkExtends = row.Extends; - 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); - } - } - - 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 is not null) - *ppvSig = blobPtr + (reader.StartOffset - (uint)metadata.BlobStream.StartOffset); - if (pcbSig is not null) - *pcbSig = reader.Length; - } - - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - void Dispose(bool disposing) { - metadata = null; - var addrToFreeTmp = Interlocked.Exchange(ref addrToFree, IntPtr.Zero); - blobPtr = null; - if (addrToFreeTmp != IntPtr.Zero) - Marshal.FreeHGlobal(addrToFreeTmp); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/StreamIStream.cs b/Plugins/dnlib/DotNet/Pdb/Dss/StreamIStream.cs deleted file mode 100644 index be1b60e..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/StreamIStream.cs +++ /dev/null @@ -1,158 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.InteropServices.ComTypes; - -namespace dnlib.DotNet.Pdb.Dss { - /// - /// Implements and uses a as the underlying - /// stream. - /// - sealed class StreamIStream : IStream { - readonly Stream stream; - readonly string name; - - const int STG_E_INVALIDFUNCTION = unchecked((int)0x80030001); - - /// - /// Constructor - /// - /// Source stream - public StreamIStream(Stream stream) - : this(stream, string.Empty) { - } - - /// - /// Constructor - /// - /// Source stream - /// Name of original file or null if unknown. - public StreamIStream(Stream stream, string name) { - this.stream = stream ?? throw new ArgumentNullException(nameof(stream)); - this.name = name ?? string.Empty; - } - - /// - public void Clone(out IStream ppstm) { - Marshal.ThrowExceptionForHR(STG_E_INVALIDFUNCTION); - throw new Exception(); - } - - /// - public void Commit(int grfCommitFlags) => stream.Flush(); - - /// - public void CopyTo(IStream pstm, long cb, IntPtr pcbRead, IntPtr pcbWritten) { - if (cb > int.MaxValue) - cb = int.MaxValue; - else if (cb < 0) - cb = 0; - int sizeToRead = (int)cb; - - if (stream.Position + sizeToRead < sizeToRead || stream.Position + sizeToRead > stream.Length) - sizeToRead = (int)(stream.Length - Math.Min(stream.Position, stream.Length)); - - var buffer = new byte[sizeToRead]; - Read(buffer, sizeToRead, pcbRead); - if (pcbRead != IntPtr.Zero) - Marshal.WriteInt64(pcbRead, Marshal.ReadInt32(pcbRead)); - pstm.Write(buffer, buffer.Length, pcbWritten); - if (pcbWritten != IntPtr.Zero) - 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; - - cb = stream.Read(pv, 0, cb); - - if (pcbRead != IntPtr.Zero) - Marshal.WriteInt32(pcbRead, cb); - } - - /// - public void Revert() { - } - - enum STREAM_SEEK { - SET = 0, - CUR = 1, - END = 2, - } - - /// - public void Seek(long dlibMove, int dwOrigin, IntPtr plibNewPosition) { - switch ((STREAM_SEEK)dwOrigin) { - case STREAM_SEEK.SET: - stream.Position = dlibMove; - break; - - case STREAM_SEEK.CUR: - stream.Position += dlibMove; - break; - - case STREAM_SEEK.END: - stream.Position = stream.Length + dlibMove; - break; - } - - if (plibNewPosition != IntPtr.Zero) - Marshal.WriteInt64(plibNewPosition, stream.Position); - } - - /// - public void SetSize(long libNewSize) => stream.SetLength(libNewSize); - - enum STATFLAG { - DEFAULT = 0, - NONAME = 1, - NOOPEN = 2, - } - - enum STGTY { - STORAGE = 1, - STREAM = 2, - LOCKBYTES = 3, - PROPERTY = 4, - } - - /// - public void Stat(out System.Runtime.InteropServices.ComTypes.STATSTG pstatstg, int grfStatFlag) { - var s = new System.Runtime.InteropServices.ComTypes.STATSTG(); - - // s.atime = ???; - s.cbSize = stream.Length; - s.clsid = Guid.Empty; - // s.ctime = ???; - s.grfLocksSupported = 0; - s.grfMode = 2; - s.grfStateBits = 0; - // s.mtime = ???; - if ((grfStatFlag & (int)STATFLAG.NONAME) == 0) - s.pwcsName = name; - s.reserved = 0; - s.type = (int)STGTY.STREAM; - - 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) { - stream.Write(pv, 0, cb); - if (pcbWritten != IntPtr.Zero) - Marshal.WriteInt32(pcbWritten, cb); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentImpl.cs deleted file mode 100644 index 650797d..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentImpl.cs +++ /dev/null @@ -1,95 +0,0 @@ -// 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 => document; - public SymbolDocumentImpl(ISymUnmanagedDocument document) => this.document = document; - - public override Guid CheckSumAlgorithmId { - get { - document.GetCheckSumAlgorithmId(out var guid); - return guid; - } - } - - public override Guid DocumentType { - get { - document.GetDocumentType(out var guid); - return guid; - } - } - - public override Guid Language { - get { - document.GetLanguage(out var guid); - return guid; - } - } - - public override Guid LanguageVendor { - get { - document.GetLanguageVendor(out var guid); - return guid; - } - } - - public override string URL { - get { - document.GetURL(0, out uint 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 { - document.GetCheckSum(0, out uint bufSize, null); - var buffer = new byte[bufSize]; - document.GetCheckSum((uint)buffer.Length, out bufSize, buffer); - return buffer; - } - } - - 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 is null) { - var sourceCode = SourceCode; - if (sourceCode is not null) - customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; - else - customDebugInfos = Array2.Empty(); - } - return customDebugInfos; - } - } - PdbCustomDebugInfo[] customDebugInfos; - - public override MDToken? MDToken => null; - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentWriter.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentWriter.cs deleted file mode 100644 index 564fab8..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolDocumentWriter.cs +++ /dev/null @@ -1,17 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics.SymbolStore; - -namespace dnlib.DotNet.Pdb.Dss { - 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) { - 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/Plugins/dnlib/DotNet/Pdb/Dss/SymbolMethodImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolMethodImpl.cs deleted file mode 100644 index bc96f6e..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolMethodImpl.cs +++ /dev/null @@ -1,112 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -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(SymbolReaderImpl reader, ISymUnmanagedMethod method) { - this.reader = reader; - this.method = method; - asyncMethod = method as ISymUnmanagedAsyncMethod; - } - - public override int Token { - get { - method.GetToken(out uint result); - return (int)result; - } - } - - public override SymbolScope RootScope { - get { - if (rootScope is null) { - method.GetRootScope(out var scope); - Interlocked.CompareExchange(ref rootScope, scope is null ? null : new SymbolScopeImpl(scope, this, null), null); - } - return rootScope; - } - } - volatile SymbolScope rootScope; - - public override IList SequencePoints { - get { - if (sequencePoints is null) { - method.GetSequencePointCount(out uint seqPointCount); - var seqPoints = new SymbolSequencePoint[seqPointCount]; - - 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) - 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], - Document = new SymbolDocumentImpl(unDocs[i]), - Line = lines[i], - Column = columns[i], - EndLine = endLines[i], - EndColumn = endColumns[i], - }; - } - sequencePoints = seqPoints; - } - return sequencePoints; - } - } - volatile SymbolSequencePoint[] sequencePoints; - - public int AsyncKickoffMethod { - get { - if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) - return 0; - return (int)asyncMethod.GetKickoffMethod(); - } - } - - public uint? AsyncCatchHandlerILOffset { - get { - if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) - return null; - if (!asyncMethod.HasCatchHandlerILOffset()) - return null; - return asyncMethod.GetCatchHandlerILOffset(); - } - } - - public IList AsyncStepInfos { - get { - if (asyncMethod is null || !asyncMethod.IsAsyncMethod()) - return null; - if (asyncStepInfos is null) { - 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]); - asyncStepInfos = res; - } - return asyncStepInfos; - } - } - volatile SymbolAsyncStepInfo[] asyncStepInfos; - - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => - reader.GetCustomDebugInfos(this, method, body, result); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs deleted file mode 100644 index 2b27978..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolNamespaceImpl.cs +++ /dev/null @@ -1,22 +0,0 @@ -// 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) => ns = @namespace; - - public override string Name { - get { - ns.GetName(0, out uint 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/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderImpl.cs deleted file mode 100644 index 2fb78d4..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderImpl.cs +++ /dev/null @@ -1,159 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -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 { - ModuleDef module; - ISymUnmanagedReader reader; - object[] objsToKeepAlive; - - const int E_FAIL = unchecked((int)0x80004005); - - 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; - - public override int UserEntryPoint { - get { - int hr = reader.GetUserEntryPoint(out uint token); - if (hr == E_FAIL) - token = 0; - else - Marshal.ThrowExceptionForHR(hr); - return (int)token; - } - } - - public override IList Documents { - get { - if (documents is 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]; - for (uint i = 0; i < numDocs; i++) - docs[i] = new SymbolDocumentImpl(unDocs[i]); - documents = docs; - } - return documents; - } - } - volatile SymbolDocument[] documents; - - public override void Initialize(ModuleDef module) => this.module = module; - - public override SymbolMethod GetMethod(MethodDef method, int version) { - int hr = reader.GetMethodByVersion(method.MDToken.Raw, version, out var unMethod); - if (hr == E_FAIL) - return null; - Marshal.ThrowExceptionForHR(hr); - 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 is not null) - result.Add(asyncMethod); - - const string CDI_NAME = "MD2"; - reader.GetSymAttribute(method.MDToken.Raw, CDI_NAME, 0, out uint 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); - } - - 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 is not null) - result.Add(new PdbSourceLinkCustomDebugInfo(sourceLinkData)); - var sourceServerData = GetSourceServerData(); - if (sourceServerData is not 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 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; - } - } - return null; - } - - byte[] GetSourceServerData() { - if (reader is ISymUnmanagedSourceServerModule srcSrvModule) { - var srcSrvData = IntPtr.Zero; - try { - // 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; - } - } - finally { - if (srcSrvData != IntPtr.Zero) - Marshal.FreeCoTaskMem(srcSrvData); - } - } - return null; - } - - public override void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - void Dispose(bool disposing) { - (reader as ISymUnmanagedDispose)?.Destroy(); - var o = objsToKeepAlive; - if (o is not null) { - foreach (var obj in o) - (obj as IDisposable)?.Dispose(); - } - module = null; - reader = null; - objsToKeepAlive = null; - } - - 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) - 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/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs deleted file mode 100644 index c8ddfb9..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolReaderWriterFactory.cs +++ /dev/null @@ -1,214 +0,0 @@ -// 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 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")] - 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.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); - - [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); - - [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; - - 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 is null) - return null; - var debugDir = pdbContext.CodeViewDebugDirectory; - if (debugDir is null) - return null; - if (!pdbContext.TryGetCodeViewData(out var pdbGuid, out uint age)) - return null; - - unmanagedReader = CreateSymUnmanagedReader(pdbContext.Options); - if (unmanagedReader is 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.MatchesModule(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; - - 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; - 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 ??= 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; - - 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; - 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 ??= Type.GetTypeFromCLSID(CLSID_CorSymWriter_SxS)); - - return null; - } - - 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 SymbolWriter Create(PdbWriterOptions options, Stream pdbStream, string pdbFileName) => - new SymbolWriterImpl(CreateSymUnmanagedWriter2(options), pdbFileName, pdbStream, options, ownsStream: false); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolScopeImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolScopeImpl.cs deleted file mode 100644 index ffbdc58..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolScopeImpl.cs +++ /dev/null @@ -1,136 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -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 => method; - public override SymbolScope Parent => parent; - - public override int StartOffset { - get { - scope.GetStartOffset(out uint result); - return (int)result; - } - } - - public override int EndOffset { - get { - scope.GetEndOffset(out uint result); - return (int)result; - } - } - - public override IList Children { - get { - if (children is 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]; - for (uint i = 0; i < numScopes; i++) - scopes[i] = new SymbolScopeImpl(unScopes[i], method, this); - children = scopes; - } - return children; - } - } - volatile SymbolScope[] children; - - public override IList Locals { - get { - if (locals is 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]; - for (uint i = 0; i < numVars; i++) - vars[i] = new SymbolVariableImpl(unVars[i]); - locals = vars; - } - return locals; - } - } - volatile SymbolVariable[] locals; - - public override IList Namespaces { - get { - if (namespaces is 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]; - for (uint i = 0; i < numNss; i++) - nss[i] = new SymbolNamespaceImpl(unNss[i]); - namespaces = nss; - } - return namespaces; - } - } - volatile SymbolNamespace[] namespaces; - - public override IList CustomDebugInfos => Array2.Empty(); - public override PdbImportScope ImportScope => null; - - public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { - var scope2 = scope as ISymUnmanagedScope2; - if (scope2 is null) - return Array2.Empty(); - scope2.GetConstants(0, out uint numCs, null); - if (numCs == 0) - return Array2.Empty(); - 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); - unc.GetValue(out object 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; - } - - string GetName(ISymUnmanagedConstant unc) { - unc.GetName(0, out uint 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); - int hr = unc.GetSignature(0, out uint bufSize, null); - if (bufSize == 0 || (hr < 0 && hr != E_FAIL && hr != E_NOTIMPL)) - return Array2.Empty(); - var buffer = new byte[bufSize]; - hr = unc.GetSignature((uint)buffer.Length, out bufSize, buffer); - Debug.Assert(hr == 0); - if (hr != 0) - return Array2.Empty(); - return buffer; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolVariableImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolVariableImpl.cs deleted file mode 100644 index 62347c6..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolVariableImpl.cs +++ /dev/null @@ -1,42 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.DotNet.Pdb.WindowsPdb; - -namespace dnlib.DotNet.Pdb.Dss { - sealed class SymbolVariableImpl : SymbolVariable { - readonly ISymUnmanagedVariable variable; - - public SymbolVariableImpl(ISymUnmanagedVariable variable) => this.variable = variable; - - public override int Index { - get { - variable.GetAddressField1(out uint result); - return (int)result; - } - } - - public override PdbLocalAttributes Attributes { - get { - variable.GetAttributes(out uint result); - if ((result & (uint)CorSymVarFlag.VAR_IS_COMP_GEN) != 0) - return PdbLocalAttributes.DebuggerHidden; - return PdbLocalAttributes.None; - } - } - - public override string Name { - get { - variable.GetName(0, out uint 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 override PdbCustomDebugInfo[] CustomDebugInfos => Array2.Empty(); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolWriterImpl.cs b/Plugins/dnlib/DotNet/Pdb/Dss/SymbolWriterImpl.cs deleted file mode 100644 index 875dddd..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Dss/SymbolWriterImpl.cs +++ /dev/null @@ -1,167 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -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; - readonly string pdbFileName; - readonly Stream pdbStream; - readonly bool ownsStream; - readonly bool isDeterministic; - bool closeCalled; - - public override bool IsDeterministic => isDeterministic; - 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)); - asyncMethodWriter = writer as ISymUnmanagedAsyncMethodPropertiesWriter; - this.pdbStream = pdbStream ?? throw new ArgumentNullException(nameof(pdbStream)); - this.pdbFileName = pdbFileName; - this.ownsStream = ownsStream; - isDeterministic = (options & PdbWriterOptions.Deterministic) != 0 && writer is ISymUnmanagedWriter6; - } - - public override void Close() { - if (closeCalled) - return; - closeCalled = true; - writer.Close(); - } - - public override void CloseMethod() => writer.CloseMethod(); - public override void CloseScope(int endOffset) => writer.CloseScope((uint)endOffset); - - public override void DefineAsyncStepInfo(uint[] yieldOffsets, uint[] breakpointOffset, uint[] breakpointMethod) { - if (asyncMethodWriter is 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 override void DefineCatchHandlerILOffset(uint catchHandlerOffset) { - if (asyncMethodWriter is null) - throw new InvalidOperationException(); - asyncMethodWriter.DefineCatchHandlerILOffset(catchHandlerOffset); - } - - public override void DefineConstant(string name, object value, uint sigToken) => writer.DefineConstant2(name, value, sigToken); - - 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 is null ? null : new SymbolDocumentWriter(unDocWriter); - } - - public override void DefineKickoffMethod(uint kickoffMethod) { - 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 is null) - throw new ArgumentException("document isn't a non-null SymbolDocumentWriter instance"); - writer.DefineSequencePoints(doc.SymUnmanagedDocumentWriter, arraySize, offsets, lines, columns, endLines, endColumns); - } - - public override void OpenMethod(MDToken method) => writer.OpenMethod(method.Raw); - - public override int OpenScope(int startOffset) { - writer.OpenScope((uint)startOffset, out uint result); - return (int)result; - } - - 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 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; - - 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); - return true; - } - else if (writer is ISymUnmanagedWriter7 writer7) { - fixed (byte* p = checksumBytes) - writer7.UpdateSignatureByHashingContent(new IntPtr(p), (uint)checksumBytes.Length); - } - } - - writer.GetDebugInfo(out pIDD, 0, out uint size, null); - 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 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 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 override unsafe void SetSourceServerData(byte[] data) { - if (data is null) - return; - if (writer is ISymUnmanagedWriter8 writer8) { - fixed (void* p = data) - writer8.SetSourceServerData(new IntPtr(p), (uint)data.Length); - } - } - - public override unsafe void SetSourceLinkData(byte[] data) { - if (data is null) - return; - if (writer is ISymUnmanagedWriter8 writer8) { - fixed (void* p = data) - writer8.SetSourceLinkData(new IntPtr(p), (uint)data.Length); - } - } - - public override void Dispose() { - Marshal.FinalReleaseComObject(writer); - if (ownsStream) - pdbStream.Dispose(); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs b/Plugins/dnlib/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs deleted file mode 100644 index c69e14f..0000000 --- a/Plugins/dnlib/DotNet/Pdb/IMAGE_DEBUG_DIRECTORY.cs +++ /dev/null @@ -1,21 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.PE; - -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 ImageDebugType Type; - public uint SizeOfData; - public uint AddressOfRawData; - public uint PointerToRawData; -#pragma warning restore 1591 - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/DbiDocument.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiDocument.cs deleted file mode 100644 index fde9e87..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiDocument.cs +++ /dev/null @@ -1,61 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Diagnostics.SymbolStore; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiDocument : SymbolDocument { - readonly string url; - Guid language; - Guid languageVendor; - Guid documentType; - Guid checkSumAlgorithmId; - byte[] checkSum; - byte[] sourceCode; - - 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; - byte[] SourceCode => sourceCode; - - public override PdbCustomDebugInfo[] CustomDebugInfos { - get { - if (customDebugInfos is null) { - var sourceCode = SourceCode; - if (sourceCode is not null) - customDebugInfos = new PdbCustomDebugInfo[1] { new PdbEmbeddedSourceCustomDebugInfo(sourceCode) }; - else - customDebugInfos = Array2.Empty(); - } - return customDebugInfos; - } - } - PdbCustomDebugInfo[] customDebugInfos; - - public override MDToken? MDToken => null; - - public DbiDocument(string url) { - this.url = url; - documentType = SymDocumentType.Text; - } - - public void Read(ref DataReader reader) { - reader.Position = 0; - language = reader.ReadGuid(); - languageVendor = reader.ReadGuid(); - documentType = reader.ReadGuid(); - checkSumAlgorithmId = reader.ReadGuid(); - 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/Plugins/dnlib/DotNet/Pdb/Managed/DbiFunction.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiFunction.cs deleted file mode 100644 index 0e543e0..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiFunction.cs +++ /dev/null @@ -1,118 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiFunction : SymbolMethod { - public override int Token => 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; } - public List Lines { - get => lines; - set => lines = value; - } - List lines; - - public void Read(ref DataReader reader, uint recEnd) { - reader.Position += 4; - var end = reader.ReadUInt32(); - reader.Position += 4; - var len = reader.ReadUInt32(); - reader.Position += 8; - token = reader.ReadInt32(); - Address = PdbAddress.ReadAddress(ref reader); - reader.Position += 1 + 2; - Name = PdbReader.ReadCString(ref reader); - - reader.Position = recEnd; - Root = new DbiScope(this, null, "", Address.Offset, len); - Root.Read(new RecursionCounter(), ref reader, end); - FixOffsets(new RecursionCounter(), Root); - } - - void FixOffsets(RecursionCounter counter, DbiScope scope) { - if (!counter.Increment()) - return; - - scope.startOffset -= (int)Address.Offset; - scope.endOffset -= (int)Address.Offset; - var children = scope.Children; - int count = children.Count; - for (int i = 0; i < count; i++) - FixOffsets(counter, (DbiScope)children[i]); - - counter.Decrement(); - } - - public override SymbolScope RootScope => Root; - - public override IList SequencePoints { - get { - var l = lines; - if (l is null) - return Array2.Empty(); - return l; - } - } - - const string asyncMethodInfoAttributeName = "asyncMethodInfo"; - public int AsyncKickoffMethod { - get { - var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data is null || data.Length < 4) - return 0; - return BitConverter.ToInt32(data, 0); - } - } - - public uint? AsyncCatchHandlerILOffset { - get { - var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data is null || data.Length < 8) - return null; - uint token = BitConverter.ToUInt32(data, 4); - return token == uint.MaxValue ? (uint?)null : token; - } - } - - public IList AsyncStepInfos { - get { - if (asyncStepInfos is null) - asyncStepInfos = CreateSymbolAsyncStepInfos(); - return asyncStepInfos; - } - } - volatile SymbolAsyncStepInfo[] asyncStepInfos; - - SymbolAsyncStepInfo[] CreateSymbolAsyncStepInfos() { - var data = Root.GetSymAttribute(asyncMethodInfoAttributeName); - if (data is null || data.Length < 12) - return Array2.Empty(); - int pos = 8; - int count = BitConverter.ToInt32(data, pos); - pos += 4; - if (pos + (long)count * 12 > data.Length) - return Array2.Empty(); - if (count == 0) - return Array2.Empty(); - var res = new SymbolAsyncStepInfo[count]; - for (int i = 0; i < res.Length; i++) { - res[i] = new SymbolAsyncStepInfo(BitConverter.ToUInt32(data, pos), BitConverter.ToUInt32(data, pos + 8), BitConverter.ToUInt32(data, pos + 4)); - pos += 12; - } - return res; - } - - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => - reader.GetCustomDebugInfos(this, method, body, result); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/DbiModule.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiModule.cs deleted file mode 100644 index 7016cb5..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiModule.cs +++ /dev/null @@ -1,210 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiModule { - public DbiModule() { - Functions = new List(); - Documents = new List(); - } - - public ushort StreamId { get; private set; } - uint cbSyms; - uint cbOldLines; - uint cbLines; - - public string ModuleName { get; private set; } - public string ObjectName { get; private set; } - - public List Functions { get; private set; } - public List Documents { get; private set; } - - public void Read(ref DataReader reader) { - reader.Position += 34; - StreamId = reader.ReadUInt16(); - cbSyms = reader.ReadUInt32(); - cbOldLines = reader.ReadUInt32(); - cbLines = reader.ReadUInt32(); - reader.Position += 16; - - if ((int)cbSyms < 0) - cbSyms = 0; - if ((int)cbOldLines < 0) - cbOldLines = 0; - if ((int)cbLines < 0) - cbLines = 0; - - ModuleName = PdbReader.ReadCString(ref reader); - ObjectName = PdbReader.ReadCString(ref reader); - - reader.Position = (reader.Position + 3) & (~3U); - } - - public void LoadFunctions(PdbReader pdbReader, ref DataReader reader) { - reader.Position = 0; - ReadFunctions(reader.Slice(reader.Position, cbSyms)); - - if (Functions.Count > 0) { - reader.Position += cbSyms + cbOldLines; - ReadLines(pdbReader, reader.Slice(reader.Position, cbLines)); - } - } - - void ReadFunctions(DataReader reader) { - if (reader.ReadUInt32() != 4) - throw new PdbException("Invalid signature"); - - while (reader.Position < reader.Length) { - var size = reader.ReadUInt16(); - var begin = reader.Position; - var end = begin + size; - - var type = (SymbolType)reader.ReadUInt16(); - switch (type) { - case SymbolType.S_GMANPROC: - case SymbolType.S_LMANPROC: - var func = new DbiFunction(); - func.Read(ref reader, end); - Functions.Add(func); - break; - default: - reader.Position = end; - break; - } - } - } - - void ReadLines(PdbReader pdbReader, DataReader reader) { - var docs = new Dictionary(); - - reader.Position = 0; - while (reader.Position < reader.Length) { - var sig = (ModuleStreamType)reader.ReadUInt32(); - var size = reader.ReadUInt32(); - var begin = reader.Position; - var end = (begin + size + 3) & ~3U; - - if (sig == ModuleStreamType.FileInfo) - ReadFiles(pdbReader, docs, ref reader, end); - - reader.Position = end; - } - - var sortedFuncs = new DbiFunction[Functions.Count]; - Functions.CopyTo(sortedFuncs, 0); - Array.Sort(sortedFuncs, (a, b) => a.Address.CompareTo(b.Address)); - - reader.Position = 0; - while (reader.Position < reader.Length) { - var sig = (ModuleStreamType)reader.ReadUInt32(); - var size = reader.ReadUInt32(); - var begin = reader.Position; - var end = begin + size; - - if (sig == ModuleStreamType.Lines) - ReadLines(sortedFuncs, docs, ref reader, end); - - reader.Position = end; - } - } - - void ReadFiles(PdbReader pdbReader, Dictionary documents, ref DataReader reader, uint end) { - var begin = reader.Position; - while (reader.Position < end) { - var id = reader.Position - begin; - - var nameId = reader.ReadUInt32(); - var len = reader.ReadByte(); - /*var type = */reader.ReadByte(); - var doc = pdbReader.GetDocument(nameId); - documents.Add(id, doc); - - reader.Position += len; - reader.Position = (reader.Position + 3) & (~3U); - } - } - - void ReadLines(DbiFunction[] funcs, Dictionary documents, ref DataReader reader, uint end) { - var address = PdbAddress.ReadAddress(ref reader); - - int first = 0; - int last = funcs.Length - 1; - int found = -1; - while (first <= last) { - var index = first + ((last - first) >> 1); - var addr = funcs[index].Address; - if (addr < address) { - first = index + 1; - } - else if (addr > address) { - last = index - 1; - } - else { - found = index; - break; - } - } - if (found == -1) - return; - - var flags = reader.ReadUInt16(); - reader.Position += 4; - - if (funcs[found].Lines is null) { - while (found > 0) { - var prevFunc = funcs[found - 1]; - if (prevFunc is not null && prevFunc.Address != address) - break; - found--; - } - } - else { - while (found < funcs.Length - 1 && funcs[found] is not null) { - var nextFunc = funcs[found + 1]; - if (nextFunc.Address != address) - break; - found++; - } - } - var func = funcs[found]; - if (func.Lines is not null) - return; - func.Lines = new List(); - - while (reader.Position < end) { - var document = documents[reader.ReadUInt32()]; - var count = reader.ReadUInt32(); - reader.Position += 4; - - const int LINE_ENTRY_SIZE = 8; - const int COL_ENTRY_SIZE = 4; - var lineTablePos = reader.Position; - var colTablePos = reader.Position + count * LINE_ENTRY_SIZE; - - for (uint i = 0; i < count; i++) { - reader.Position = lineTablePos + i * LINE_ENTRY_SIZE; - - var line = new SymbolSequencePoint { - Document = document - }; - line.Offset = reader.ReadInt32(); - var lineFlags = reader.ReadUInt32(); - - line.Line = (int)(lineFlags & 0x00ffffff); - line.EndLine = line.Line + (int)((lineFlags >> 24) & 0x7F); - if ((flags & 1) != 0) { - reader.Position = colTablePos + i * COL_ENTRY_SIZE; - line.Column = reader.ReadUInt16(); - line.EndColumn = reader.ReadUInt16(); - } - - func.Lines.Add(line); - } - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/DbiNamespace.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiNamespace.cs deleted file mode 100644 index abe3a88..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiNamespace.cs +++ /dev/null @@ -1,12 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.DotNet.Pdb.Symbols; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiNamespace : SymbolNamespace { - public override string Name => name; - readonly string name; - - public DbiNamespace(string ns) => name = ns; - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/DbiScope.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiScope.cs deleted file mode 100644 index 30c26fb..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiScope.cs +++ /dev/null @@ -1,202 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - 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; - - 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 => Array2.Empty(); - public override PdbImportScope ImportScope => null; - - 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(); - localsList = new List(); - namespacesList = new List(); - } - - public string Name { get; private set; } - - List oemInfos; - List constants; - - 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; - Value = value; - } - } - - 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() => $"{Name} = ({Data.Length} 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, ref DataReader reader, uint scopeEnd) { - if (!counter.Increment()) - throw new PdbException("Scopes too deep"); - - while (reader.Position < scopeEnd) { - var size = reader.ReadUInt16(); - var begin = reader.Position; - var end = begin + size; - - var type = (SymbolType)reader.ReadUInt16(); - DbiScope child = null; - uint? childEnd = null; - string name; - switch (type) { - case SymbolType.S_BLOCK32: { - reader.Position += 4; - childEnd = reader.ReadUInt32(); - var len = reader.ReadUInt32(); - var addr = PdbAddress.ReadAddress(ref reader); - name = PdbReader.ReadCString(ref reader); - child = new DbiScope(method, this, name, addr.Offset, len); - break; - } - case SymbolType.S_UNAMESPACE: - namespacesList.Add(new DbiNamespace(PdbReader.ReadCString(ref reader))); - break; - case SymbolType.S_MANSLOT: { - var variable = new DbiVariable(); - if (variable.Read(ref reader)) - localsList.Add(variable); - break; - } - case SymbolType.S_OEM: - if ((ulong)reader.Position + 20 > end) - break; - if (!ReadAndCompareBytes(ref reader, end, dotNetOemGuid)) { - Debug.Fail("Unknown OEM record GUID, not .NET GUID"); - break; - } - reader.Position += 4;// typeIndex or 0 - name = ReadUnicodeString(ref reader, end); - Debug.Assert(name is not null); - if (name is null) - break; - var data = reader.ReadBytes((int)(end - reader.Position)); - if (oemInfos is null) - oemInfos = new List(1); - oemInfos.Add(new OemInfo(name, data)); - break; - case SymbolType.S_MANCONSTANT: - uint signatureToken = reader.ReadUInt32(); - object value; - if (!NumericReader.TryReadNumeric(ref reader, end, out value)) - break; - name = PdbReader.ReadCString(ref reader); - if (constants is null) - constants = new List(); - constants.Add(new ConstantInfo(name, signatureToken, value)); - break; - case SymbolType.S_END: - break; - default: - break; - } - - reader.Position = end; - if (child is not null) { - child.Read(counter, ref reader, childEnd.Value); - childrenList.Add(child); - child = null; - } - } - counter.Decrement(); - if (reader.Position != scopeEnd) - Debugger.Break(); - } - - static string ReadUnicodeString(ref DataReader reader, uint end) { - var sb = new StringBuilder(); - for (;;) { - if ((ulong)reader.Position + 2 > end) - return null; - var c = reader.ReadChar(); - if (c == 0) - break; - sb.Append(c); - } - return sb.ToString(); - } - - static bool ReadAndCompareBytes(ref DataReader reader, uint end, byte[] bytes) { - if ((ulong)reader.Position + (uint)bytes.Length > end) - return false; - for (int i = 0; i < bytes.Length; i++) { - if (reader.ReadByte() != bytes[i]) - return false; - } - return true; - } - - public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { - 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 is null ? null : saSig.Signature as FieldSig; - if (fieldSig is null) { - Debug.Fail("Constant without a signature"); - signature = null; - } - else - signature = fieldSig.Type; - res[i] = new PdbConstant(info.Name, signature, info.Value); - } - return res; - } - - internal byte[] GetSymAttribute(string name) { - if (oemInfos is null) - return null; - foreach (var info in oemInfos) { - if (info.Name == name) - return info.Data; - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/DbiVariable.cs b/Plugins/dnlib/DotNet/Pdb/Managed/DbiVariable.cs deleted file mode 100644 index 46d6556..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/DbiVariable.cs +++ /dev/null @@ -1,39 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class DbiVariable : SymbolVariable { - public override string Name => name; - string name; - - public override PdbLocalAttributes Attributes => attributes; - PdbLocalAttributes attributes; - - public override int Index => index; - int index; - - public override PdbCustomDebugInfo[] CustomDebugInfos => Array2.Empty(); - - public bool Read(ref DataReader reader) { - index = reader.ReadInt32(); - reader.Position += 10; - 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) { - PdbLocalAttributes res = 0; - const int fCompGenx = 4; - if ((flags & fCompGenx) != 0) - res |= PdbLocalAttributes.DebuggerHidden; - return res; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/ModuleStreamType.cs b/Plugins/dnlib/DotNet/Pdb/Managed/ModuleStreamType.cs deleted file mode 100644 index c326068..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/ModuleStreamType.cs +++ /dev/null @@ -1,18 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb.Managed { - enum ModuleStreamType : uint { - Symbols = 0xF1, - Lines = 0xF2, - StringTable = 0xF3, - FileInfo = 0xF4, - FrameData = 0xF5, - InlineeLines = 0xF6, - CrossScopeImports = 0xF7, - CrossScopeExports = 0xF8, - ILLines = 0xF9, - FuncMDTokenMap = 0xFA, - TypeMDTokenMap = 0xFB, - MergedAssemblyInput = 0xFC, - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/MsfStream.cs b/Plugins/dnlib/DotNet/Pdb/Managed/MsfStream.cs deleted file mode 100644 index 95cbdf1..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/MsfStream.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - sealed class MsfStream { - public MsfStream(DataReader[] pages, uint length) { - var buf = new byte[length]; - int offset = 0; - for (int i = 0; i < pages.Length; i++) { - var page = pages[i]; - page.Position = 0; - int len = Math.Min((int)page.Length, (int)(length - offset)); - page.ReadBytes(buf, offset, len); - offset += len; - } - Content = ByteArrayDataReaderFactory.CreateReader(buf); - } - - public DataReader Content; - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/NumericLeaf.cs b/Plugins/dnlib/DotNet/Pdb/Managed/NumericLeaf.cs deleted file mode 100644 index acedd24..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/NumericLeaf.cs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/Managed/NumericReader.cs b/Plugins/dnlib/DotNet/Pdb/Managed/NumericReader.cs deleted file mode 100644 index 566a854..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/NumericReader.cs +++ /dev/null @@ -1,101 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - static class NumericReader { - public static bool TryReadNumeric(ref DataReader reader, ulong end, out object value) { - value = null; - ulong position = reader.Position; - if (position + 2 > end) - return false; - var numLeaf = (NumericLeaf)reader.ReadUInt16(); - if (numLeaf < NumericLeaf.LF_NUMERIC) { - value = (short)numLeaf; - return true; - } - - switch (numLeaf) { - case NumericLeaf.LF_CHAR: - if (position > end) - return false; - value = reader.ReadSByte(); - return true; - - case NumericLeaf.LF_SHORT: - if (position + 2 > end) - return false; - value = reader.ReadInt16(); - return true; - - case NumericLeaf.LF_USHORT: - if (position + 2 > end) - return false; - value = reader.ReadUInt16(); - return true; - - case NumericLeaf.LF_LONG: - if (position + 4 > end) - return false; - value = reader.ReadInt32(); - return true; - - case NumericLeaf.LF_ULONG: - if (position + 4 > end) - return false; - value = reader.ReadUInt32(); - return true; - - case NumericLeaf.LF_REAL32: - if (position + 4 > end) - return false; - value = reader.ReadSingle(); - return true; - - case NumericLeaf.LF_REAL64: - if (position + 8 > end) - return false; - value = reader.ReadDouble(); - return true; - - case NumericLeaf.LF_QUADWORD: - if (position + 8 > end) - return false; - value = reader.ReadInt64(); - return true; - - case NumericLeaf.LF_UQUADWORD: - if (position + 8 > end) - return false; - value = reader.ReadUInt64(); - return true; - - case NumericLeaf.LF_VARSTRING: - if (position + 2 > end) - return false; - int varStrLen = reader.ReadUInt16(); - if (position + (uint)varStrLen > end) - return false; - value = reader.ReadUtf8String(varStrLen); - return true; - - case NumericLeaf.LF_VARIANT: - if (position + 0x10 > end) - return false; - int v0 = reader.ReadInt32(); - int v1 = reader.ReadInt32(); - int v2 = reader.ReadInt32(); - int v3 = reader.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/Plugins/dnlib/DotNet/Pdb/Managed/PdbAddress.cs b/Plugins/dnlib/DotNet/Pdb/Managed/PdbAddress.cs deleted file mode 100644 index 91ad32a..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/PdbAddress.cs +++ /dev/null @@ -1,144 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - /// - /// An address in the image - /// - [DebuggerDisplay("{Section}:{Offset}")] - readonly struct PdbAddress : IEquatable, IComparable { - /// - /// Section - /// - public readonly ushort Section; - - /// - /// Offset in - /// - public readonly uint Offset; - - /// - /// Constructor - /// - /// Section - /// Offset in - public PdbAddress(ushort section, int offset) { - Section = section; - Offset = (uint)offset; - } - - /// - /// Constructor - /// - /// Section - /// Offset in - public PdbAddress(ushort section, uint offset) { - Section = section; - Offset = offset; - } - - /// - /// Returns true if is less than or equal to - /// - /// First - /// Second - /// - public static bool operator <=(PdbAddress a, PdbAddress b) => a.CompareTo(b) <= 0; - - /// - /// Returns true if is less than - /// - /// First - /// Second - /// - public static bool operator <(PdbAddress a, PdbAddress b) => a.CompareTo(b) < 0; - - /// - /// Returns true if is greater than or equal to - /// - /// First - /// Second - /// - public static bool operator >=(PdbAddress a, PdbAddress b) => a.CompareTo(b) >= 0; - - /// - /// Returns true if is greater than - /// - /// First - /// Second - /// - public static bool operator >(PdbAddress a, PdbAddress b) => a.CompareTo(b) > 0; - - /// - /// Returns true if is equal to - /// - /// First - /// Second - /// - public static bool operator ==(PdbAddress a, PdbAddress b) => a.Equals(b); - - /// - /// Returns true if is not equal to - /// - /// First - /// Second - /// - public static bool operator !=(PdbAddress a, PdbAddress b) => !a.Equals(b); - - /// - /// Compares this instance with and returns less than 0 if it's - /// less than , 0 if it's equal to and - /// greater than 0 if it's greater than - /// - /// Other instance - /// - public int CompareTo(PdbAddress other) { - if (Section != other.Section) - return Section.CompareTo(other.Section); - return Offset.CompareTo(other.Offset); - } - - /// - /// Compares this to another instance - /// - /// The other one - /// true if they're equal - public bool Equals(PdbAddress other) => Section == other.Section && Offset == other.Offset; - - /// - /// Compares this to another instance - /// - /// The other one - /// true if they're equal - public override bool Equals(object obj) { - if (!(obj is PdbAddress)) - return false; - return Equals((PdbAddress)obj); - } - - /// - /// Gets the hash code - /// - /// Hash code - public override int GetHashCode() => (Section << 16) ^ (int)Offset; - - /// - /// ToString() override - /// - /// - public override string ToString() => $"{Section:X4}:{Offset:X8}"; - - /// - /// Reads a 32-bit offset followed by a 16-bit section and creates a new - /// - /// Reader - /// - public static PdbAddress ReadAddress(ref DataReader reader) { - uint offs = reader.ReadUInt32(); - return new PdbAddress(reader.ReadUInt16(), offs); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/PdbException.cs b/Plugins/dnlib/DotNet/Pdb/Managed/PdbException.cs deleted file mode 100644 index 43b8e3e..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/PdbException.cs +++ /dev/null @@ -1,43 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.Serialization; - -namespace dnlib.DotNet.Pdb.Managed { - /// - /// Exception that is thrown when encounters an error. - /// - [Serializable] - sealed class PdbException : Exception { - /// - /// Constructor - /// - public PdbException() { - } - - /// - /// Constructor - /// - /// Exception message - public PdbException(string message) - : base($"Failed to read PDB: {message}") { - } - - /// - /// Constructor - /// - /// Inner exception - public PdbException(Exception innerException) - : base($"Failed to read PDB: {innerException.Message}", innerException) { - } - - /// - /// Constructor - /// - /// - /// - public PdbException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/PdbReader.cs b/Plugins/dnlib/DotNet/Pdb/Managed/PdbReader.cs deleted file mode 100644 index 92a20cc..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/PdbReader.cs +++ /dev/null @@ -1,367 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections; -using System.Collections.Generic; -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 { - /// - /// A managed PDB reader implementation for .NET modules. - /// - sealed class PdbReader : SymbolReader { - MsfStream[] streams; - Dictionary names; - Dictionary strings; - List modules; - ModuleDef module; - - const int STREAM_ROOT = 0; - const int STREAM_NAMES = 1; - const int STREAM_TPI = 2; - const int STREAM_DBI = 3; - const ushort STREAM_INVALID_INDEX = ushort.MaxValue; - - Dictionary documents; - Dictionary functions; - byte[] sourcelinkData; - byte[] srcsrvData; - uint entryPt; - - public override PdbFileKind PdbFileKind => PdbFileKind.WindowsPDB; - - uint Age { get; set; } - Guid Guid { get; set; } - - internal bool MatchesModule => expectedGuid == Guid && expectedAge == Age; - readonly Guid expectedGuid; - readonly uint expectedAge; - - public PdbReader(Guid expectedGuid, uint expectedAge) { - this.expectedGuid = expectedGuid; - this.expectedAge = expectedAge; - } - - public override void Initialize(ModuleDef module) => this.module = module; - - /// - /// Read the PDB in the specified stream. - /// - /// PDB file data reader - public void Read(DataReader reader) { - try { - ReadInternal(ref reader); - } - catch (Exception ex) { - if (ex is PdbException) - throw; - throw new PdbException(ex); - } - finally { - streams = null; - names = null; - strings = null; - modules = null; - } - } - - static uint RoundUpDiv(uint value, uint divisor) => (value + divisor - 1) / divisor; - - void ReadInternal(ref DataReader reader) { - string sig = reader.ReadString(30, Encoding.ASCII); - if (sig != "Microsoft C/C++ MSF 7.00\r\n\u001ADS\0") - throw new PdbException("Invalid signature"); - reader.Position += 2; - - uint pageSize = reader.ReadUInt32(); - /*uint fpm = */reader.ReadUInt32(); - uint pageCount = reader.ReadUInt32(); - uint rootSize = reader.ReadUInt32(); - reader.ReadUInt32(); - var numOfRootPages = RoundUpDiv(rootSize, pageSize); - var numOfPtrPages = RoundUpDiv(numOfRootPages * 4, pageSize); - if (pageCount * pageSize != reader.Length) - throw new PdbException("File size mismatch"); - - var pages = new DataReader[pageCount]; - uint offset = 0; - for (uint i = 0; i < pageCount; i++) { - pages[i] = reader.Slice(offset, pageSize); - offset += pageSize; - } - - var rootPages = new DataReader[numOfRootPages]; - int pageIndex = 0; - for (int i = 0; i < numOfPtrPages && pageIndex < numOfRootPages; i++) { - var ptrPage = pages[reader.ReadUInt32()]; - ptrPage.Position = 0; - for (; ptrPage.Position < ptrPage.Length && pageIndex < numOfRootPages; pageIndex++) - rootPages[pageIndex] = pages[ptrPage.ReadUInt32()]; - } - - ReadRootDirectory(new MsfStream(rootPages, rootSize), pages, pageSize); - - ReadNames(); - if (!MatchesModule) - return; - ReadStringTable(); - var tokenMapStream = ReadModules(); - - documents = new Dictionary(StringComparer.OrdinalIgnoreCase); - foreach (var module in modules) { - if (IsValidStreamIndex(module.StreamId)) - module.LoadFunctions(this, ref streams[module.StreamId].Content); - } - - if (IsValidStreamIndex(tokenMapStream ?? STREAM_INVALID_INDEX)) - ApplyRidMap(ref streams[tokenMapStream.Value].Content); - - functions = new Dictionary(); - foreach (var module in modules) { - foreach (var func in module.Functions) { - func.reader = this; - 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; - - void ReadRootDirectory(MsfStream stream, DataReader[] pages, uint pageSize) { - uint streamNum = stream.Content.ReadUInt32(); - var streamSizes = new uint[streamNum]; - for (int i = 0; i < streamSizes.Length; i++) - streamSizes[i] = stream.Content.ReadUInt32(); - - streams = new MsfStream[streamNum]; - for (int i = 0; i < streamSizes.Length; i++) { - if (streamSizes[i] == 0xffffffff) { - streams[i] = null; - continue; - } - var pageCount = RoundUpDiv(streamSizes[i], pageSize); - var streamPages = new DataReader[pageCount]; - for (int j = 0; j < streamPages.Length; j++) - streamPages[j] = pages[stream.Content.ReadUInt32()]; - streams[i] = new MsfStream(streamPages, streamSizes[i]); - } - } - - void ReadNames() { - ref var stream = ref streams[STREAM_NAMES].Content; - stream.Position = 8; - Age = stream.ReadUInt32(); - Guid = stream.ReadGuid(); - - uint nameSize = stream.ReadUInt32(); - var nameData = stream.Slice(stream.Position, nameSize); - stream.Position += nameSize; - - /*uint entryCount = */stream.ReadUInt32(); - uint entryCapacity = stream.ReadUInt32(); - var entryOk = new BitArray(stream.ReadBytes(stream.ReadInt32() * 4)); - if (stream.ReadUInt32() != 0) - throw new NotSupportedException(); - - names = new Dictionary(StringComparer.OrdinalIgnoreCase); - entryCapacity = Math.Min(entryCapacity, (uint)entryOk.Count); - for (int i = 0; i < entryCapacity; i++) { - if (!entryOk[i]) - continue; - - var pos = stream.ReadUInt32(); - var streamId = stream.ReadUInt32(); - nameData.Position = pos; - var streamName = ReadCString(ref nameData); - names[streamName] = streamId; - } - } - - void ReadStringTable() { - if (!names.TryGetValue("/names", out uint streamId)) - throw new PdbException("String table not found"); - - ref var stream = ref streams[streamId].Content; - stream.Position = 8; - - uint strSize = stream.ReadUInt32(); - var strData = stream.Slice(stream.Position, strSize); - stream.Position += strSize; - - uint count = stream.ReadUInt32(); - strings = new Dictionary((int)count); - for (uint i = 0; i < count; i++) { - var pos = stream.ReadUInt32(); - if (pos == 0) - continue; - strData.Position = pos; - strings[pos] = ReadCString(ref strData); - } - } - - static uint ReadSizeField(ref DataReader reader) { - int size = reader.ReadInt32(); - return size <= 0 ? 0 : (uint)size; - } - - 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; - uint gpmodiSize = ReadSizeField(ref stream); // gpmodiSize - uint otherSize = 0; - otherSize += ReadSizeField(ref stream); // secconSize - otherSize += ReadSizeField(ref stream); // secmapSize - otherSize += ReadSizeField(ref stream); // filinfSize - otherSize += ReadSizeField(ref stream); // tsmapSize - stream.ReadUInt32(); // mfcIndex - uint dbghdrSize = ReadSizeField(ref stream); - otherSize += ReadSizeField(ref stream); // ecinfoSize - stream.Position += 8; - - var moduleStream = stream.Slice(stream.Position, gpmodiSize); - while (moduleStream.Position < moduleStream.Length) { - var module = new DbiModule(); - module.Read(ref moduleStream); - modules.Add(module); - } - - if (IsValidStreamIndex(symrecStream)) - ReadGlobalSymbols(ref streams[symrecStream].Content); - - if (dbghdrSize != 0) { - stream.Position += gpmodiSize; - stream.Position += otherSize; - stream.Position += 12; - return stream.ReadUInt16(); - } - return null; - } - - internal DbiDocument GetDocument(uint nameId) { - var name = strings[nameId]; - - if (!documents.TryGetValue(name, out var doc)) { - doc = new DbiDocument(name); - - if (names.TryGetValue($"/src/files/{name}", out uint streamId)) - doc.Read(ref streams[streamId].Content); - documents.Add(name, doc); - } - return doc; - } - - void ReadGlobalSymbols(ref DataReader reader) { - reader.Position = 0; - while (reader.Position < reader.Length) { - var size = reader.ReadUInt16(); - var begin = reader.Position; - var end = begin + size; - - if ((SymbolType)reader.ReadUInt16() == SymbolType.S_PUB32) { - reader.Position += 4; - var offset = reader.ReadUInt32(); - reader.Position += 2; - var name = ReadCString(ref reader); - - if (name == "COM+_Entry_Point") { - entryPt = offset; - break; - } - } - - reader.Position = end; - } - } - - void ApplyRidMap(ref DataReader reader) { - reader.Position = 0; - var map = new uint[reader.Length / 4]; - for (int i = 0; i < map.Length; i++) - map[i] = reader.ReadUInt32(); - - foreach (var module in modules) { - foreach (var func in module.Functions) { - var rid = (uint)func.Token & 0x00ffffff; - rid = map[rid]; - func.token = (int)((func.Token & 0xff000000) | rid); - } - } - - if (entryPt != 0) { - var rid = entryPt & 0x00ffffff; - rid = map[rid]; - entryPt = (entryPt & 0xff000000) | rid; - } - } - - 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; - } - - public override IList Documents { - get { - if (documentsResult is null) { - var docs = new SymbolDocument[documents.Count]; - int i = 0; - foreach (var kv in documents) - docs[i++] = kv.Value; - documentsResult = docs; - } - return documentsResult; - } - } - volatile SymbolDocument[] documentsResult; - - public override int UserEntryPoint => (int)entryPt; - - 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 not null) - result.Add(asyncMethod); - - var cdiData = symMethod.Root.GetSymAttribute(CDI_NAME); - if (cdiData is null) - return; - PdbCustomDebugInfoReader.Read(method, body, result, cdiData); - } - - public override void GetCustomDebugInfos(int token, GenericParamContext gpContext, IList result) { - if (token == 0x00000001) - GetCustomDebugInfos_ModuleDef(result); - } - - void GetCustomDebugInfos_ModuleDef(IList result) { - if (sourcelinkData is not null) - result.Add(new PdbSourceLinkCustomDebugInfo(sourcelinkData)); - if (srcsrvData is not null) - result.Add(new PdbSourceServerCustomDebugInfo(srcsrvData)); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/SymbolReaderFactory.cs b/Plugins/dnlib/DotNet/Pdb/Managed/SymbolReaderFactory.cs deleted file mode 100644 index 8962eb6..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/SymbolReaderFactory.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.IO; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Managed { - /// - /// Creates a instance - /// - static class SymbolReaderFactory { - /// - /// 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(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { - if (pdbStream is null) - return null; - try { - var debugDir = pdbContext.CodeViewDebugDirectory; - if (debugDir is null) - 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.MatchesModule) - return pdbReader; - return null; - } - catch (PdbException) { - } - catch (IOException) { - } - finally { - pdbStream?.Dispose(); - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Managed/SymbolType.cs b/Plugins/dnlib/DotNet/Pdb/Managed/SymbolType.cs deleted file mode 100644 index 66a1bec..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Managed/SymbolType.cs +++ /dev/null @@ -1,201 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb.Managed { - enum SymbolType : ushort { - S_COMPILE = 0x0001, - S_REGISTER_16t = 0x0002, - S_CONSTANT_16t = 0x0003, - S_UDT_16t = 0x0004, - S_SSEARCH = 0x0005, - S_END = 0x0006, - S_SKIP = 0x0007, - S_CVRESERVE = 0x0008, - S_OBJNAME_ST = 0x0009, - S_ENDARG = 0x000A, - S_COBOLUDT_16t = 0x000B, - S_MANYREG_16t = 0x000C, - S_RETURN = 0x000D, - S_ENTRYTHIS = 0x000E, - - S_BPREL16 = 0x0100, - S_LDATA16 = 0x0101, - S_GDATA16 = 0x0102, - S_PUB16 = 0x0103, - S_LPROC16 = 0x0104, - S_GPROC16 = 0x0105, - S_THUNK16 = 0x0106, - S_BLOCK16 = 0x0107, - S_WITH16 = 0x0108, - S_LABEL16 = 0x0109, - S_CEXMODEL16 = 0x010A, - S_VFTABLE16 = 0x010B, - S_REGREL16 = 0x010C, - - S_BPREL32_16t = 0x0200, - S_LDATA32_16t = 0x0201, - S_GDATA32_16t = 0x0202, - S_PUB32_16t = 0x0203, - S_LPROC32_16t = 0x0204, - S_GPROC32_16t = 0x0205, - S_THUNK32_ST = 0x0206, - S_BLOCK32_ST = 0x0207, - S_WITH32_ST = 0x0208, - S_LABEL32_ST = 0x0209, - S_CEXMODEL32 = 0x020A, - S_VFTABLE32_16t = 0x020B, - S_REGREL32_16t = 0x020C, - S_LTHREAD32_16t = 0x020D, - S_GTHREAD32_16t = 0x020E, - S_SLINK32 = 0x020F, - - S_LPROCMIPS_16t = 0x0300, - S_GPROCMIPS_16t = 0x0301, - - S_PROCREF_ST = 0x0400, - S_DATAREF_ST = 0x0401, - S_ALIGN = 0x0402, - S_LPROCREF_ST = 0x0403, - S_OEM = 0x0404, - - S_TI16_MAX = 0x1000, - S_REGISTER_ST = 0x1001, - S_CONSTANT_ST = 0x1002, - S_UDT_ST = 0x1003, - S_COBOLUDT_ST = 0x1004, - S_MANYREG_ST = 0x1005, - S_BPREL32_ST = 0x1006, - S_LDATA32_ST = 0x1007, - S_GDATA32_ST = 0x1008, - S_PUB32_ST = 0x1009, - S_LPROC32_ST = 0x100A, - S_GPROC32_ST = 0x100B, - S_VFTABLE32 = 0x100C, - S_REGREL32_ST = 0x100D, - S_LTHREAD32_ST = 0x100E, - S_GTHREAD32_ST = 0x100F, - S_LPROCMIPS_ST = 0x1010, - S_GPROCMIPS_ST = 0x1011, - S_FRAMEPROC = 0x1012, - S_COMPILE2_ST = 0x1013, - S_MANYREG2_ST = 0x1014, - S_LPROCIA64_ST = 0x1015, - S_GPROCIA64_ST = 0x1016, - S_LOCALSLOT_ST = 0x1017, - S_PARAMSLOT_ST = 0x1018, - S_ANNOTATION = 0x1019, - S_GMANPROC_ST = 0x101A, - S_LMANPROC_ST = 0x101B, - S_RESERVED1 = 0x101C, - S_RESERVED2 = 0x101D, - S_RESERVED3 = 0x101E, - S_RESERVED4 = 0x101F, - S_LMANDATA_ST = 0x1020, - S_GMANDATA_ST = 0x1021, - S_MANFRAMEREL_ST = 0x1022, - S_MANREGISTER_ST = 0x1023, - S_MANSLOT_ST = 0x1024, - S_MANMANYREG_ST = 0x1025, - S_MANREGREL_ST = 0x1026, - S_MANMANYREG2_ST = 0x1027, - S_MANTYPREF = 0x1028, - S_UNAMESPACE_ST = 0x1029, - - S_ST_MAX = 0x1100, - S_OBJNAME = 0x1101, - S_THUNK32 = 0x1102, - S_BLOCK32 = 0x1103, - S_WITH32 = 0x1104, - S_LABEL32 = 0x1105, - S_REGISTER = 0x1106, - S_CONSTANT = 0x1107, - S_UDT = 0x1108, - S_COBOLUDT = 0x1109, - S_MANYREG = 0x110A, - S_BPREL32 = 0x110B, - S_LDATA32 = 0x110C, - S_GDATA32 = 0x110D, - S_PUB32 = 0x110E, - S_LPROC32 = 0x110F, - S_GPROC32 = 0x1110, - S_REGREL32 = 0x1111, - S_LTHREAD32 = 0x1112, - S_GTHREAD32 = 0x1113, - S_LPROCMIPS = 0x1114, - S_GPROCMIPS = 0x1115, - S_COMPILE2 = 0x1116, - S_MANYREG2 = 0x1117, - S_LPROCIA64 = 0x1118, - S_GPROCIA64 = 0x1119, - S_LOCALSLOT = 0x111A, - S_PARAMSLOT = 0x111B, - S_LMANDATA = 0x111C, - S_GMANDATA = 0x111D, - S_MANFRAMEREL = 0x111E, - S_MANREGISTER = 0x111F, - S_MANSLOT = 0x1120, - S_MANMANYREG = 0x1121, - S_MANREGREL = 0x1122, - S_MANMANYREG2 = 0x1123, - S_UNAMESPACE = 0x1124, - S_PROCREF = 0x1125, - S_DATAREF = 0x1126, - S_LPROCREF = 0x1127, - S_ANNOTATIONREF = 0x1128, - S_TOKENREF = 0x1129, - S_GMANPROC = 0x112A, - S_LMANPROC = 0x112B, - S_TRAMPOLINE = 0x112C, - S_MANCONSTANT = 0x112D, - S_ATTR_FRAMEREL = 0x112E, - S_ATTR_REGISTER = 0x112F, - S_ATTR_REGREL = 0x1130, - S_ATTR_MANYREG = 0x1131, - S_SEPCODE = 0x1132, - S_LOCAL_2005 = 0x1133, - S_DEFRANGE_2005 = 0x1134, - S_DEFRANGE2_2005 = 0x1135, - S_SECTION = 0x1136, - S_COFFGROUP = 0x1137, - S_EXPORT = 0x1138, - S_CALLSITEINFO = 0x1139, - S_FRAMECOOKIE = 0x113A, - S_DISCARDED = 0x113B, - S_COMPILE3 = 0x113C, - S_ENVBLOCK = 0x113D, - S_LOCAL = 0x113E, - S_DEFRANGE = 0x113F, - S_DEFRANGE_SUBFIELD = 0x1140, - S_DEFRANGE_REGISTER = 0x1141, - S_DEFRANGE_FRAMEPOINTER_REL = 0x1142, - S_DEFRANGE_SUBFIELD_REGISTER = 0x1143, - S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE = 0x1144, - S_DEFRANGE_REGISTER_REL = 0x1145, - S_LPROC32_ID = 0x1146, - S_GPROC32_ID = 0x1147, - S_LPROCMIPS_ID = 0x1148, - S_GPROCMIPS_ID = 0x1149, - S_LPROCIA64_ID = 0x114A, - S_GPROCIA64_ID = 0x114B, - S_BUILDINFO = 0x114C, - S_INLINESITE = 0x114D, - S_INLINESITE_END = 0x114E, - S_PROC_ID_END = 0x114F, - S_DEFRANGE_HLSL = 0x1150, - S_GDATA_HLSL = 0x1151, - S_LDATA_HLSL = 0x1152, - S_FILESTATIC = 0x1153, - S_LOCAL_DPC_GROUPSHARED = 0x1154, - S_LPROC32_DPC = 0x1155, - S_LPROC32_DPC_ID = 0x1156, - S_DEFRANGE_DPC_PTR_TAG = 0x1157, - S_DPC_SYM_TAG_MAP = 0x1158, - S_ARMSWITCHTABLE = 0x1159, - S_CALLEES = 0x115A, - S_CALLERS = 0x115B, - S_POGODATA = 0x115C, - S_INLINESITE2 = 0x115D, - S_HEAPALLOCSITE = 0x115E, - - S_RECTYPE_MAX, - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbConstant.cs b/Plugins/dnlib/DotNet/Pdb/PdbConstant.cs deleted file mode 100644 index 11fb6fa..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbConstant.cs +++ /dev/null @@ -1,80 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet.Pdb { - /// - /// A constant in a method scope, eg. "const int SomeConstant = 123;" - /// - public sealed class PdbConstant : IHasCustomDebugInformation { - string name; - TypeSig type; - object value; - - /// - /// Gets/sets the name - /// - public string Name { - get => name; - set => name = value; - } - - /// - /// Gets/sets the type of the constant - /// - public TypeSig Type { - get => type; - set => type = value; - } - - /// - /// Gets/sets the value of the constant - /// - public object Value { - get => value; - set => this.value = value; - } - - /// - /// Constructor - /// - public PdbConstant() { - } - - /// - /// Constructor - /// - /// Name of constant - /// Type of constant - /// Constant value - public PdbConstant(string name, TypeSig type, object value) { - this.name = name; - this.type = type; - this.value = value; - } - - /// - public int HasCustomDebugInformationTag => 25; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// Gets all custom debug infos - /// - public IList CustomDebugInfos => customDebugInfos; - readonly IList customDebugInfos = new List(); - - /// - /// ToString() - /// - /// - public override string ToString() { - var type = Type; - 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/Plugins/dnlib/DotNet/Pdb/PdbCustomDebugInfo.cs b/Plugins/dnlib/DotNet/Pdb/PdbCustomDebugInfo.cs deleted file mode 100644 index 6b013d0..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbCustomDebugInfo.cs +++ /dev/null @@ -1,1309 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Threading; -using dnlib.DotNet.Emit; - -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, - - // Values 0x00-0xFF are reserved for Windows PDB CDIs. - - /// - /// Unknown - /// - Unknown = int.MinValue, - - /// - /// - /// - TupleElementNames_PortablePdb, - - /// - /// - /// - DefaultNamespace, - - /// - /// - /// - DynamicLocalVariables, - - /// - /// - /// - EmbeddedSource, - - /// - /// - /// - SourceLink, - - /// - /// - /// - SourceServer, - - /// - /// - /// - AsyncMethod, - - /// - /// - /// - IteratorMethod, - - /// - /// - /// - CompilationMetadataReferences, - - /// - /// - /// - CompilationOptions, - - /// - /// - /// - TypeDefinitionDocuments, - - /// - /// - /// - EditAndContinueStateMachineStateMap, - - /// - /// - /// - PrimaryConstructorInformationBlob, - } - - /// - /// 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; } - - /// - /// Gets the custom debug info guid, see - /// - public abstract Guid Guid { 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 Guid guid; - readonly byte[] data; - - /// - /// Gets the custom debug info kind - /// - public override PdbCustomDebugInfoKind Kind => kind; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => guid; - - /// - /// Gets the data - /// - public byte[] Data => data; - - /// - /// Constructor - /// - /// Custom debug info kind - /// Raw custom debug info data - public PdbUnknownCustomDebugInfo(PdbCustomDebugInfoKind kind, byte[] data) { - this.kind = kind; - this.data = data ?? throw new ArgumentNullException(nameof(data)); - guid = Guid.Empty; - } - - /// - /// Constructor - /// - /// Custom debug info guid - /// Raw custom debug info data - public PdbUnknownCustomDebugInfo(Guid guid, byte[] data) { - kind = PdbCustomDebugInfoKind.Unknown; - this.data = data ?? throw new ArgumentNullException(nameof(data)); - this.guid = guid; - } - } - - /// - /// Contains sizes of using groups - /// - public sealed class PdbUsingGroupsCustomDebugInfo : PdbCustomDebugInfo { - readonly IList usingCounts; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.UsingGroups; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets the using counts - /// - public IList UsingCounts => usingCounts; - - /// - /// Constructor - /// - public PdbUsingGroupsCustomDebugInfo() => usingCounts = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbUsingGroupsCustomDebugInfo(int capacity) => usingCounts = new List(capacity); - } - - /// - /// Contains a reference to another method that contains the import strings - /// - public sealed class PdbForwardMethodInfoCustomDebugInfo : PdbCustomDebugInfo { - IMethodDefOrRef method; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.ForwardMethodInfo; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets/sets the referenced method - /// - public IMethodDefOrRef Method { - get => 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 => PdbCustomDebugInfoKind.ForwardModuleInfo; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets/sets the referenced method - /// - public IMethodDefOrRef Method { - get => 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 readonly 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 - /// - 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 IList scopes; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => CustomDebugInfoGuids.StateMachineHoistedLocalScopes; - - /// - /// Gets the scopes - /// - public IList Scopes => scopes; - - /// - /// Constructor - /// - public PdbStateMachineHoistedLocalScopesCustomDebugInfo() => scopes = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbStateMachineHoistedLocalScopesCustomDebugInfo(int capacity) => scopes = new List(capacity); - } - - /// - /// Contains the state machine type - /// - public sealed class PdbStateMachineTypeNameCustomDebugInfo : PdbCustomDebugInfo { - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.StateMachineTypeName; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// 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 IList locals; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DynamicLocals; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets the dynamic locals - /// - public IList Locals => locals; - - /// - /// Constructor - /// - public PdbDynamicLocalsCustomDebugInfo() => locals = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbDynamicLocalsCustomDebugInfo(int capacity) => locals = new List(capacity); - } - - /// - /// Dynamic local info - /// - public sealed class PdbDynamicLocal { - readonly IList flags; - string name; - Local local; - - /// - /// Gets the dynamic flags - /// - public 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). - /// If null is written, is returned instead. - /// - public string Name { - get { - var n = name; - if (n is not null) - return n; - return local?.Name; - } - set => name = value; - } - - /// - /// true if it's a constant and not a variable ( is null) - /// - public bool IsConstant => Local is null; - - /// - /// true if it's a variable ( is not 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). - /// - public Local Local { - get => local; - set => local = value; - } - - /// - /// Constructor - /// - public PdbDynamicLocal() => flags = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbDynamicLocal(int capacity) => flags = new List(capacity); - } - - /// - /// Contains the EnC local variable slot map - /// - public sealed class PdbEditAndContinueLocalSlotMapCustomDebugInfo : PdbCustomDebugInfo { - readonly byte[] data; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap; - - /// - /// Gets the custom debug info guid, see - /// - 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 => data; - - /// - /// Constructor - /// - /// Raw custom debug info data - public PdbEditAndContinueLocalSlotMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data)); - } - - /// - /// Contains the EnC lambda map - /// - public sealed class PdbEditAndContinueLambdaMapCustomDebugInfo : PdbCustomDebugInfo { - readonly byte[] data; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.EditAndContinueLambdaMap; - - /// - /// Gets the custom debug info guid, see - /// - 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 => data; - - /// - /// Constructor - /// - /// Raw custom debug info data - public PdbEditAndContinueLambdaMapCustomDebugInfo(byte[] data) => this.data = data ?? throw new ArgumentNullException(nameof(data)); - } - - /// - /// Contains tuple element names for local variables and constants - /// - public sealed class PdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo { - readonly IList names; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets the tuple element names - /// - public IList Names => names; - - /// - /// Constructor - /// - public PdbTupleElementNamesCustomDebugInfo() => names = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbTupleElementNamesCustomDebugInfo(int capacity) => names = new List(capacity); - } - - /// - /// Tuple element name info - /// - public sealed class PdbTupleElementNames { - readonly 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 is not null) - return n; - return local?.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 => local; - set => local = value; - } - - /// - /// true if it's a constant. Constants have a scope ( and ) - /// - public bool IsConstant => local is null; - - /// - /// true if it's a variable. Variables don't have a scope ( and ) - /// - public bool IsVariable => local is not null; - - /// - /// Gets/sets the start of the scope or null. Only constants have a scope. - /// - public Instruction ScopeStart { - 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 => scopeEnd; - set => scopeEnd = value; - } - - /// - /// Gets the tuple element names - /// - public IList TupleElementNames => tupleElementNames; - - /// - /// Constructor - /// - public PdbTupleElementNames() => tupleElementNames = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PdbTupleElementNames(int capacity) => tupleElementNames = new List(capacity); - } - - /// - /// Contains tuple element names for local variables and constants - /// - public sealed class PortablePdbTupleElementNamesCustomDebugInfo : PdbCustomDebugInfo { - readonly IList names; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TupleElementNames_PortablePdb; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => CustomDebugInfoGuids.TupleElementNames; - - /// - /// Gets the tuple element names - /// - public IList Names => names; - - /// - /// Constructor - /// - public PortablePdbTupleElementNamesCustomDebugInfo() => names = new List(); - - /// - /// Constructor - /// - /// Initial capacity of - public PortablePdbTupleElementNamesCustomDebugInfo(int capacity) => names = new List(capacity); - } - - /// - /// Async method stepping info - /// - /// It's internal and translated to a - /// - sealed class PdbAsyncMethodSteppingInformationCustomDebugInfo : PdbCustomDebugInfo { - readonly IList asyncStepInfos; - - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.Unknown; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => CustomDebugInfoGuids.AsyncMethodSteppingInformationBlob; - - /// - /// Gets the catch handler instruction or null - /// - public Instruction CatchHandler { get; set; } - - /// - /// Gets all async step infos - /// - public IList AsyncStepInfos => asyncStepInfos; - - /// - /// Constructor - /// - public PdbAsyncMethodSteppingInformationCustomDebugInfo() => asyncStepInfos = new List(); - } - - /// - /// Default namespace - /// - public sealed class PdbDefaultNamespaceCustomDebugInfo : PdbCustomDebugInfo { - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.DefaultNamespace; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => 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 => PdbCustomDebugInfoKind.DynamicLocalVariables; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => 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 => PdbCustomDebugInfoKind.EmbeddedSource; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => 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 => PdbCustomDebugInfoKind.SourceLink; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => CustomDebugInfoGuids.SourceLink; - - /// - /// Gets the source link file contents - /// - public byte[] FileBlob { get; set; } - - /// - /// Constructor - /// - public PdbSourceLinkCustomDebugInfo() { - } - - /// - /// Constructor - /// - /// 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; - } - - /// - /// Async method info - /// - public sealed class PdbAsyncMethodCustomDebugInfo : PdbCustomDebugInfo { - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.AsyncMethod; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - readonly 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 IList StepInfos => asyncStepInfos; - - /// - /// Constructor - /// - public PdbAsyncMethodCustomDebugInfo() => asyncStepInfos = new List(); - - /// - /// Constructor - /// - /// Default capacity for - public PdbAsyncMethodCustomDebugInfo(int stepInfosCapacity) => asyncStepInfos = new List(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 => PdbCustomDebugInfoKind.IteratorMethod; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => Guid.Empty; - - /// - /// Gets the kickoff method - /// - public MethodDef KickoffMethod { get; set; } - - /// - /// Constructor - /// - public PdbIteratorMethodCustomDebugInfo() { - } - - /// - /// Constructor - /// - /// 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>(); - } - - /// - /// Links a TypeDef with no method IL with a PDB document. - /// - public class PdbTypeDefinitionDocumentsDebugInfo : PdbCustomDebugInfo { - /// - /// Returns - /// - public override PdbCustomDebugInfoKind Kind => PdbCustomDebugInfoKind.TypeDefinitionDocuments; - - /// - /// Gets the custom debug info guid, see - /// - public override Guid Guid => CustomDebugInfoGuids.TypeDefinitionDocuments; - - /// - /// List of documents associated with the type - /// - 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); - } - - sealed class PdbTypeDefinitionDocumentsDebugInfoMD : PdbTypeDefinitionDocumentsDebugInfo { - readonly ModuleDef readerModule; - readonly IList documentTokens; - - protected override void InitializeDocuments() { - var list = new List(documentTokens.Count); - 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); - } - - public PdbTypeDefinitionDocumentsDebugInfoMD(ModuleDef readerModule, IList documentTokens) { - this.readerModule = readerModule; - this.documentTokens = documentTokens; - } - } - - /// - /// 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, - } - - /// - /// 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/Plugins/dnlib/DotNet/Pdb/PdbDocument.cs b/Plugins/dnlib/DotNet/Pdb/PdbDocument.cs deleted file mode 100644 index 6f25bbe..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbDocument.cs +++ /dev/null @@ -1,126 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet.Pdb.Symbols; - -namespace dnlib.DotNet.Pdb { - /// - /// A PDB document - /// - [DebuggerDisplay("{Url}")] - public sealed class PdbDocument : IHasCustomDebugInformation { - /// - /// Gets/sets the document URL - /// - public string Url { get; set; } - - /// - /// Gets/sets the language GUID. See - /// - public Guid Language { get; set; } - - /// - /// Gets/sets the language vendor GUID. See - /// - public Guid LanguageVendor { get; set; } - - /// - /// Gets/sets the document type GUID. See - /// - public Guid DocumentType { get; set; } - - /// - /// Gets/sets the checksum algorithm ID. See - /// - public Guid CheckSumAlgorithmId { get; set; } - - /// - /// Gets/sets the checksum - /// - public byte[] CheckSum { get; set; } - - /// - public int HasCustomDebugInformationTag => 22; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// Gets all custom debug infos - /// - public IList CustomDebugInfos => customDebugInfos; - IList customDebugInfos; - - /// - /// Gets the Metadata token of the document if available. - /// - public MDToken? MDToken { get; internal set; } - - /// - /// Default constructor - /// - public PdbDocument() { - } - - /// - /// Constructor - /// - /// A instance - public PdbDocument(SymbolDocument symDoc) : this(symDoc, partial: false) { - } - - PdbDocument(SymbolDocument symDoc, bool partial) { - if (symDoc is 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); - MDToken = symDoc.MDToken; - } - - /// - /// Constructor - /// - /// Document URL - /// 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) { - Url = url; - Language = language; - LanguageVendor = languageVendor; - DocumentType = documentType; - CheckSumAlgorithmId = checkSumAlgorithmId; - CheckSum = checkSum; - } - - /// - public override int GetHashCode() => StringComparer.OrdinalIgnoreCase.GetHashCode(Url ?? string.Empty); - - /// - public override bool Equals(object obj) { - var other = obj as PdbDocument; - if (other is null) - return false; - return StringComparer.OrdinalIgnoreCase.Equals(Url ?? string.Empty, other.Url ?? string.Empty); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbDocumentConstants.cs b/Plugins/dnlib/DotNet/Pdb/PdbDocumentConstants.cs deleted file mode 100644 index 4002545..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbDocumentConstants.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -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"); - - 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"); -#pragma warning restore 1591 // Missing XML comment for publicly visible type or member - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbFileKind.cs b/Plugins/dnlib/DotNet/Pdb/PdbFileKind.cs deleted file mode 100644 index 1ec945f..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbFileKind.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb { - /// - /// PDB file kind - /// - public enum PdbFileKind { - /// - /// Windows PDB - /// - WindowsPDB, - - /// - /// Portable PDB - /// - PortablePDB, - - /// - /// Embedded portable PDB - /// - EmbeddedPortablePDB, - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbImport.cs b/Plugins/dnlib/DotNet/Pdb/PdbImport.cs deleted file mode 100644 index d300d91..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbImport.cs +++ /dev/null @@ -1,424 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Diagnostics; - -namespace dnlib.DotNet.Pdb { - /// - /// Import scope - /// - public sealed class PdbImportScope : IHasCustomDebugInformation { - readonly IList imports = new List(); - - /// - /// Constructor - /// - public PdbImportScope() { - } - - /// - /// Gets/sets the parent import scope - /// - public PdbImportScope Parent { get; set; } - - /// - /// Gets all imports - /// - public IList Imports => imports; - - /// - /// true if is not empty - /// - public bool HasImports => imports.Count > 0; - - /// - public int HasCustomDebugInformationTag => 26; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// Gets all custom debug infos - /// - public IList CustomDebugInfos => customDebugInfos; - readonly IList customDebugInfos = new List(); - } - - /// - /// 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 => 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() => $"{Kind}: {TargetNamespace}"; - } - - /// - /// Import assembly, namespace - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbImportAssemblyNamespace : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {TargetAssembly} {TargetNamespace}"; - } - - /// - /// Import type - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbImportType : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {TargetType}"; - } - - /// - /// Import xml namespace - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbImportXmlNamespace : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias} = {TargetNamespace}"; - } - - /// - /// Import assembly reference alias - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbImportAssemblyReferenceAlias : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias}"; - } - - /// - /// Alias assembly reference - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbAliasAssemblyReference : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias} = {TargetAssembly}"; - } - - /// - /// Alias namespace - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbAliasNamespace : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias} = {TargetNamespace}"; - } - - /// - /// Alias assembly namespace - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbAliasAssemblyNamespace : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias} = {TargetAssembly} {TargetNamespace}"; - } - - /// - /// Alias type - /// - [DebuggerDisplay("{GetDebuggerString(),nq}")] - public sealed class PdbAliasType : PdbImport { - /// - /// Returns - /// - public sealed override PdbImportDefinitionKind Kind => 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() => $"{Kind}: {Alias} = {TargetType}"; - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbLocal.cs b/Plugins/dnlib/DotNet/Pdb/PdbLocal.cs deleted file mode 100644 index 52e406d..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbLocal.cs +++ /dev/null @@ -1,74 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Emit; - -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 => 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 => (Attributes & PdbLocalAttributes.DebuggerHidden) != 0; - set { - if (value) - Attributes |= PdbLocalAttributes.DebuggerHidden; - else - Attributes &= ~PdbLocalAttributes.DebuggerHidden; - } - } - - /// - public int HasCustomDebugInformationTag => 24; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// Gets all custom debug infos - /// - public IList CustomDebugInfos => customDebugInfos; - readonly IList customDebugInfos = new List(); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbLocalAttributes.cs b/Plugins/dnlib/DotNet/Pdb/PdbLocalAttributes.cs deleted file mode 100644 index e126c28..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbLocalAttributes.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/PdbMethod.cs b/Plugins/dnlib/DotNet/Pdb/PdbMethod.cs deleted file mode 100644 index c364a5b..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbMethod.cs +++ /dev/null @@ -1,19 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb { - /// - /// A PDB method - /// - public sealed class PdbMethod { - /// - /// Gets/sets the root scope. It contains all scopes of the method, using namespaces, variables and constants - /// - public PdbScope Scope { get; set; } - - /// - /// Constructor - /// - public PdbMethod() { - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbReaderContext.cs b/Plugins/dnlib/DotNet/Pdb/PdbReaderContext.cs deleted file mode 100644 index 74f57e8..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbReaderContext.cs +++ /dev/null @@ -1,69 +0,0 @@ -// 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 is not null; - public ImageDebugDirectory CodeViewDebugDirectory => codeViewDebugDir; - public PdbReaderOptions Options { get; } - - public PdbReaderContext(IPEImage peImage, PdbReaderOptions options) { - this.peImage = peImage; - Options = options; - 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) => 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) - return false; - if (reader.ReadUInt32() != 0x53445352) - return false; - guid = reader.ReadGuid(); - age = reader.ReadUInt32(); - pdbFilename = reader.TryReadZeroTerminatedUtf8String(); - return pdbFilename is not null; - } - - DataReader GetCodeViewDataReader() { - if (codeViewDebugDir is null) - return default; - return CreateReader(codeViewDebugDir.AddressOfRawData, codeViewDebugDir.SizeOfData); - } - - public DataReader CreateReader(RVA rva, uint size) { - if (rva == 0 || size == 0) - return default; - var reader = peImage.CreateReader(rva, size); - if (reader.Length != size) - return default; - return reader; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbReaderOptions.cs b/Plugins/dnlib/DotNet/Pdb/PdbReaderOptions.cs deleted file mode 100644 index 4ee55d8..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbReaderOptions.cs +++ /dev/null @@ -1,44 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/PdbScope.cs b/Plugins/dnlib/DotNet/Pdb/PdbScope.cs deleted file mode 100644 index 1537dc8..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbScope.cs +++ /dev/null @@ -1,91 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet.Pdb { - /// - /// A PDB scope - /// - [DebuggerDisplay("{Start} - {End}")] - public sealed class PdbScope : IHasCustomDebugInformation { - readonly IList scopes = new List(); - readonly IList locals = new List(); - readonly IList namespaces = new List(); - readonly IList constants = new List(); - - /// - /// Constructor - /// - public PdbScope() { - } - - /// - /// Gets/sets the first instruction - /// - public Instruction Start { get; set; } - - /// - /// Gets/sets the last instruction. It's null if it ends at the end of the method. - /// - public Instruction End { get; set; } - - /// - /// Gets all child scopes - /// - public IList Scopes => scopes; - - /// - /// true if is not empty - /// - public bool HasScopes => scopes.Count > 0; - - /// - /// Gets all locals in this scope - /// - public IList Variables => locals; - - /// - /// true if is not empty - /// - public bool HasVariables => locals.Count > 0; - - /// - /// Gets all namespaces (Windows PDBs). Portable PDBs use - /// - public IList Namespaces => namespaces; - - /// - /// true if is not empty - /// - public bool HasNamespaces => namespaces.Count > 0; - - /// - /// Gets/sets the import scope (Portable PDBs). Windows PDBs use - /// - public PdbImportScope ImportScope { get; set; } - - /// - /// Gets all constants - /// - public IList Constants => constants; - - /// - /// true if is not empty - /// - public bool HasConstants => constants.Count > 0; - - /// - public int HasCustomDebugInformationTag => 23; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// Gets all custom debug infos - /// - public IList CustomDebugInfos => customDebugInfos; - readonly IList customDebugInfos = new List(); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbState.cs b/Plugins/dnlib/DotNet/Pdb/PdbState.cs deleted file mode 100644 index 3914656..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbState.cs +++ /dev/null @@ -1,465 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet.Emit; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.Threading; - -namespace dnlib.DotNet.Pdb { - /// - /// PDB state for a - /// - 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; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// 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; set; } - - /// - /// Gets/sets the user entry point method. - /// - public MethodDef UserEntryPoint { - get => userEntryPoint; - set => userEntryPoint = value; - } - - /// - /// Gets all PDB documents - /// - public IEnumerable Documents { - get { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { - return new List(docDict.Values); - } finally { theLock.ExitWriteLock(); } -#else - return docDict.Values; -#endif - } - } - - /// - /// true if is not empty - /// - public bool HasDocuments { - get { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return docDict.Count > 0; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - - } - } - - /// - /// Constructor - /// - /// Module - /// PDB file kind - public PdbState(ModuleDef module, PdbFileKind pdbFileKind) { - if (module is null) - throw new ArgumentNullException(nameof(module)); - compiler = CalculateCompiler(module); - PdbFileKind = pdbFileKind; - originalPdbFileKind = pdbFileKind; - } - - /// - /// Constructor - /// - /// A instance - /// Owner module - public PdbState(SymbolReader reader, ModuleDefMD module) { - if (module is null) - throw new ArgumentNullException(nameof(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; - - var documents = reader.Documents; - int count = documents.Count; - for (int i = 0; i < count; i++) - Add_NoLock(documents[i]); - } - - /// - /// Adds - /// - /// New document - /// if it wasn't inserted, or the already existing document - /// if it was already inserted. - public PdbDocument Add(PdbDocument doc) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return Add_NoLock(doc); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - 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; - } - - 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); - if (symDoc.MDToken.HasValue) - tokenToDocument.Add(symDoc.MDToken.Value, doc); - return doc; - } - - /// - /// Removes - /// - /// Document - /// true if it was removed, false if it wasn't inserted. - 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(); } -#endif - } - - /// - /// Returns an inserted instance or null if it's not been - /// inserted yet. - /// - /// A PDB document - /// The existing or null if it doesn't exist. - public PdbDocument GetExisting(PdbDocument doc) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - docDict.TryGetValue(doc, out var orig); - return orig; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Removes all documents - /// - /// - public void RemoveAllDocuments() => RemoveAllDocuments(false); - - /// - /// Removes all documents and optionally returns them - /// - /// true if all the original s - /// should be returned. - /// All s if is true - /// or null if is false. - public List RemoveAllDocuments(bool returnDocs) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - var docs = returnDocs ? new List(docDict.Values) : null; - tokenToDocument.Clear(); - docDict.Clear(); - return docs; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - internal Compiler Compiler => compiler; - - internal void InitializeMethodBody(ModuleDefMD module, MethodDef ownerMethod, CilBody body) { - if (reader is null) - return; - - var method = reader.GetMethod(ownerMethod, 1); - if (method is not null) { - var pdbMethod = new PdbMethod(); - pdbMethod.Scope = CreateScope(module, GenericParamContext.Create(ownerMethod), body, method.RootScope); - AddSequencePoints(body, method); - body.PdbMethod = pdbMethod; - } - } - - internal void InitializeCustomDebugInfos(MethodDef ownerMethod, CilBody body, IList customDebugInfos) { - if (reader is null) - return; - - var method = reader.GetMethod(ownerMethod, 1); - if (method is not null) - method.GetCustomDebugInfos(ownerMethod, body, customDebugInfos); - } - - static Compiler CalculateCompiler(ModuleDef module) { - if (module is null) - return Compiler.Other; - - foreach (var asmRef in module.GetAssemblyRefs()) { - if (asmRef.Name == nameAssemblyVisualBasic || asmRef.Name == nameAssemblyVisualBasicCore) - 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 is not null && asm.CustomAttributes.IsDefined("Microsoft.VisualBasic.Embedded")) - return Compiler.VisualBasic; -#endif - - 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; - 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 is null) - continue; - var seqPoint = new SequencePoint() { - Document = Add_NoLock(sp.Document), - StartLine = sp.Line, - StartColumn = sp.Column, - EndLine = sp.EndLine, - EndColumn = sp.EndColumn, - }; - instr.SequencePoint = seqPoint; - } - } - - struct CreateScopeState { - public SymbolScope SymScope; - public PdbScope PdbScope; - public IList Children; - public int ChildrenIndex; - } - - PdbScope CreateScope(ModuleDefMD module, GenericParamContext gpContext, CilBody body, SymbolScope symScope) { - if (symScope is null) - return null; - - // 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; - state.PdbScope = new PdbScope() { - Start = GetInstruction(body.Instructions, state.SymScope.StartOffset, ref instrIndex), - End = GetInstruction(body.Instructions, state.SymScope.EndOffset + endIsInclusiveValue, ref instrIndex), - }; - 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 - continue; - } - var local = body.Variables[localIndex]; - var name = symLocal.Name; - local.SetName(name); - var attributes = symLocal.Attributes; - local.SetAttributes(attributes); - var pdbLocal = new PdbLocal(local, name, attributes); - cdis = symLocal.CustomDebugInfos; - int count2 = cdis.Count; - for (int j = 0; j < count2; j++) - pdbLocal.CustomDebugInfos.Add(cdis[j]); - state.PdbScope.Variables.Add(pdbLocal); - } - - 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); - for (int i = 0; i < constants.Count; i++) { - var constant = constants[i]; - var type = constant.Type.RemovePinnedAndModifiers(); - 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: - 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: - 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 is null) - constant.Value = string.Empty; - } - else - Debug.Assert(PdbFileKind == PdbFileKind.PortablePDB || PdbFileKind == PdbFileKind.EmbeddedPortablePDB); - 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 is not 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.Children; -do_return: - if (state.ChildrenIndex < state.Children.Count) { - var child = state.Children[state.ChildrenIndex]; - stack.Push(state); - state = new CreateScopeState() { SymScope = child }; - goto recursive_call; - } - - if (stack.Count == 0) - return state.PdbScope; - - // Return from recursive call, and execute the last part of the for loop - var newPdbScope = state.PdbScope; - state = stack.Pop(); - state.PdbScope.Scopes.Add(newPdbScope); - state.ChildrenIndex++; - goto do_return; - } - - static Instruction GetInstruction(IList instrs, int offset, ref int index) { - if (instrs.Count > 0 && offset > instrs[instrs.Count - 1].Offset) - return null; - for (int i = index; i < instrs.Count; i++) { - var instr = instrs[i]; - if (instr.Offset < offset) - continue; - if (instr.Offset == offset) { - index = i; - return instr; - } - break; - } - for (int i = 0; i < index; i++) { - var instr = instrs[i]; - if (instr.Offset < offset) - continue; - if (instr.Offset == offset) { - index = i; - return instr; - } - break; - } - 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 { - Other, - VisualBasic, - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/PdbUtils.cs b/Plugins/dnlib/DotNet/Pdb/PdbUtils.cs deleted file mode 100644 index d5a2181..0000000 --- a/Plugins/dnlib/DotNet/Pdb/PdbUtils.cs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/Portable/DocumentNameReader.cs b/Plugins/dnlib/DotNet/Pdb/Portable/DocumentNameReader.cs deleted file mode 100644 index ee63d76..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/DocumentNameReader.cs +++ /dev/null @@ -1,98 +0,0 @@ -// 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[] prevSepChars; - int prevSepCharsLength; - byte[] prevSepCharBytes; - int prevSepCharBytesCount; - - public DocumentNameReader(BlobStream blobStream) { - docNamePartDict = new Dictionary(); - this.blobStream = blobStream; - sb = new StringBuilder(); - - prevSepChars = new char[2]; - prevSepCharsLength = 0; - prevSepCharBytes = new byte[3]; - prevSepCharBytesCount = 0; - } - - public string ReadDocumentName(uint offset) { - sb.Length = 0; - if (!blobStream.TryCreateReader(offset, out var reader)) - return string.Empty; - var sepChars = ReadSeparatorChar(ref reader, out int sepCharsLength); - bool needSep = false; - while (reader.Position < reader.Length) { - if (needSep) - sb.Append(sepChars, 0, sepCharsLength); - needSep = !(sepCharsLength == 1 && sepChars[0] == '\0'); - var part = ReadDocumentNamePart(reader.ReadCompressedUInt32()); - sb.Append(part); - if (sb.Length > MAX_NAME_LENGTH) { - sb.Length = MAX_NAME_LENGTH; - break; - } - } - return sb.ToString(); - } - - string ReadDocumentNamePart(uint offset) { - if (docNamePartDict.TryGetValue(offset, out var name)) - return name; - if (!blobStream.TryCreateReader(offset, out var reader)) - return string.Empty; - name = reader.ReadUtf8String((int)reader.BytesLeft); - docNamePartDict.Add(offset, name); - return name; - } - - char[] ReadSeparatorChar(ref DataReader reader, out int charLength) { - if (prevSepCharBytesCount != 0 && prevSepCharBytesCount <= reader.Length) { - var pos = reader.Position; - bool ok = true; - for (int i = 0; i < prevSepCharBytesCount; i++) { - if (i >= prevSepCharBytes.Length || reader.ReadByte() != prevSepCharBytes[i]) { - ok = false; - break; - } - } - if (ok) { - charLength = prevSepCharsLength; - return prevSepChars; - } - reader.Position = pos; - } - - var decoder = Encoding.UTF8.GetDecoder(); - var bytes = new byte[1]; - prevSepCharBytesCount = 0; - for (int i = 0; ; i++) { - byte b = reader.ReadByte(); - prevSepCharBytesCount++; - if (i == 0 && b == 0) - break; - if (i < prevSepCharBytes.Length) - prevSepCharBytes[i] = b; - bytes[0] = b; - bool isLastByte = reader.Position + 1 == reader.Length; - decoder.Convert(bytes, 0, 1, prevSepChars, 0, prevSepChars.Length, isLastByte, out int bytesUsed, out prevSepCharsLength, out bool completed); - if (prevSepCharsLength > 0) - break; - } - charLength = prevSepCharsLength; - return prevSepChars; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs b/Plugins/dnlib/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs deleted file mode 100644 index c497919..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/ImportDefinitionKindUtils.cs +++ /dev/null @@ -1,42 +0,0 @@ -// 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: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/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobReader.cs b/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobReader.cs deleted file mode 100644 index 7dad6eb..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobReader.cs +++ /dev/null @@ -1,133 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Pdb.Portable { - // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PortablePdb-Metadata.md#imports-blob - readonly struct ImportScopeBlobReader { - 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; - if (!blobStream.TryCreateReader(imports, out var reader)) - return; - while (reader.Position < reader.Length) { - var kind = ImportDefinitionKindUtils.ToPdbImportDefinitionKind(reader.ReadCompressedUInt32()); - string targetNamespace, alias; - AssemblyRef targetAssembly; - PdbImport import; - ITypeDefOrRef targetType; - switch (kind) { - case PdbImportDefinitionKind.ImportNamespace: - // ::= ImportNamespace - targetNamespace = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbImportNamespace(targetNamespace); - break; - - case PdbImportDefinitionKind.ImportAssemblyNamespace: - // ::= ImportAssemblyNamespace - targetAssembly = TryReadAssemblyRef(reader.ReadCompressedUInt32()); - targetNamespace = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbImportAssemblyNamespace(targetAssembly, targetNamespace); - break; - - case PdbImportDefinitionKind.ImportType: - // ::= ImportType - targetType = TryReadType(reader.ReadCompressedUInt32()); - import = new PdbImportType(targetType); - break; - - case PdbImportDefinitionKind.ImportXmlNamespace: - // ::= ImportXmlNamespace - alias = ReadUTF8(reader.ReadCompressedUInt32()); - targetNamespace = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbImportXmlNamespace(alias, targetNamespace); - break; - - case PdbImportDefinitionKind.ImportAssemblyReferenceAlias: - // ::= ImportReferenceAlias - alias = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbImportAssemblyReferenceAlias(alias); - break; - - case PdbImportDefinitionKind.AliasAssemblyReference: - // ::= AliasAssemblyReference - alias = ReadUTF8(reader.ReadCompressedUInt32()); - targetAssembly = TryReadAssemblyRef(reader.ReadCompressedUInt32()); - import = new PdbAliasAssemblyReference(alias, targetAssembly); - break; - - case PdbImportDefinitionKind.AliasNamespace: - // ::= AliasNamespace - alias = ReadUTF8(reader.ReadCompressedUInt32()); - targetNamespace = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbAliasNamespace(alias, targetNamespace); - break; - - case PdbImportDefinitionKind.AliasAssemblyNamespace: - // ::= AliasAssemblyNamespace - alias = ReadUTF8(reader.ReadCompressedUInt32()); - targetAssembly = TryReadAssemblyRef(reader.ReadCompressedUInt32()); - targetNamespace = ReadUTF8(reader.ReadCompressedUInt32()); - import = new PdbAliasAssemblyNamespace(alias, targetAssembly, targetNamespace); - break; - - case PdbImportDefinitionKind.AliasType: - // ::= AliasType - alias = ReadUTF8(reader.ReadCompressedUInt32()); - targetType = TryReadType(reader.ReadCompressedUInt32()); - import = new PdbAliasType(alias, targetType); - break; - - case ImportDefinitionKindUtils.UNKNOWN_IMPORT_KIND: - import = null; - break; - - default: - Debug.Fail($"Unknown import definition kind: {kind}"); - import = null; - break; - } - if (import is not null) - result.Add(import); - } - Debug.Assert(reader.Position == reader.Length); - } - - ITypeDefOrRef TryReadType(uint codedToken) { - bool b = CodedToken.TypeDefOrRef.Decode(codedToken, out uint token); - Debug.Assert(b); - if (!b) - return null; - var type = module.ResolveToken(token) as ITypeDefOrRef; - Debug.Assert(type is not null); - return type; - } - - AssemblyRef TryReadAssemblyRef(uint rid) { - var asmRef = module.ResolveToken(0x23000000 + rid) as AssemblyRef; - Debug.Assert(asmRef is not null); - return asmRef; - } - - string ReadUTF8(uint offset) { - if (!blobStream.TryCreateReader(offset, out var reader)) - return string.Empty; - return reader.ReadUtf8String((int)reader.BytesLeft); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs b/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs deleted file mode 100644 index eac5468..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/ImportScopeBlobWriter.cs +++ /dev/null @@ -1,115 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -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 - readonly 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, DataWriter writer, BlobHeap blobHeap, IList imports) { - var blobWriter = new ImportScopeBlobWriter(helper, systemMetadata, blobHeap); - blobWriter.Write(writer, imports); - } - - uint WriteUTF8(string s) { - if (s is null) { - helper.Error("String is null"); - s = string.Empty; - } - var bytes = Encoding.UTF8.GetBytes(s); - return blobHeap.Add(bytes); - } - - void Write(DataWriter writer, IList 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.Error2("Unknown import definition kind: {0}.", import.Kind); - 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(GetTypeDefOrRefEncodedToken(((PdbImportType)import).TargetType)); - 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(GetTypeDefOrRefEncodedToken(((PdbAliasType)import).TargetType)); - break; - - default: - helper.Error2("Unknown import definition kind: {0}.", import.Kind); - return; - } - } - } - - uint GetTypeDefOrRefEncodedToken(ITypeDefOrRef tdr) { - if (tdr is null) { - helper.Error("ITypeDefOrRef is null"); - return 0; - } - var token = systemMetadata.GetToken(tdr); - if (MD.CodedToken.TypeDefOrRef.Encode(token, out uint codedToken)) - return codedToken; - helper.Error2("Could not encode token 0x{0:X8}.", token.Raw); - return 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/ListCache.cs b/Plugins/dnlib/DotNet/Pdb/Portable/ListCache.cs deleted file mode 100644 index a1e9dcd..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/ListCache.cs +++ /dev/null @@ -1,20 +0,0 @@ -// 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() => 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/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs b/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs deleted file mode 100644 index 9f13e24..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobReader.cs +++ /dev/null @@ -1,300 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Portable { - struct LocalConstantSigBlobReader { - readonly ModuleDef module; - DataReader reader; - readonly GenericParamContext gpContext; - RecursionCounter recursionCounter; - - public LocalConstantSigBlobReader(ModuleDef module, ref DataReader reader, GenericParamContext gpContext) { - this.module = module; - this.reader = reader; - this.gpContext = gpContext; - recursionCounter = default; - } - - public bool Read(out TypeSig type, out object value) { - bool b = ReadCatch(out type, out value); - Debug.Assert(!b || reader.Position == reader.Length); - return b; - } - - bool ReadCatch(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 = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.Char: - type = module.CorLibTypes.Char; - value = reader.ReadChar(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.I1: - type = module.CorLibTypes.SByte; - value = reader.ReadSByte(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.U1: - type = module.CorLibTypes.Byte; - value = reader.ReadByte(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.I2: - type = module.CorLibTypes.Int16; - value = reader.ReadInt16(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.U2: - type = module.CorLibTypes.UInt16; - value = reader.ReadUInt16(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.I4: - type = module.CorLibTypes.Int32; - value = reader.ReadInt32(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.U4: - type = module.CorLibTypes.UInt32; - value = reader.ReadUInt32(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.I8: - type = module.CorLibTypes.Int64; - value = reader.ReadInt64(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - res = true; - break; - - case ElementType.U8: - type = module.CorLibTypes.UInt64; - value = reader.ReadUInt64(); - if (reader.Position < reader.Length) - type = ReadTypeDefOrRefSig(); - 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 = ReadCatch(out type, out value); - if (res) - type = new PtrSig(type); - break; - - case ElementType.ByRef: - res = ReadCatch(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: - tdr = ReadTypeDefOrRef(); - type = tdr.ToTypeSig(); - 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 is 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 = ReadCatch(out type, out value); - if (res) - type = new CModReqdSig(tdr, type); - break; - - case ElementType.CModOpt: - tdr = ReadTypeDefOrRef(); - res = ReadCatch(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}"); - 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) { - if (tdr is TypeRef tr) { - @namespace = tr.Namespace; - name = tr.Name; - return true; - } - - if (tdr is TypeDef td) { - @namespace = td.Namespace; - name = td.Name; - return true; - } - - @namespace = null; - name = null; - return false; - } - - TypeSig ReadTypeDefOrRefSig() { - uint codedToken; - if (!reader.TryReadCompressedUInt32(out codedToken)) - return null; - ISignatureReaderHelper helper = module; - var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); - return tdr.ToTypeSig(); - } - - ITypeDefOrRef ReadTypeDefOrRef() { - uint codedToken; - if (!reader.TryReadCompressedUInt32(out codedToken)) - return null; - ISignatureReaderHelper helper = module; - var tdr = helper.ResolveTypeDefOrRef(codedToken, gpContext); - var corType = module.CorLibTypes.GetCorLibTypeSig(tdr); - if (corType is not null) - return corType.TypeDefOrRef; - return tdr; - } - - string ReadString() { - if (reader.Position == reader.Length) - return string.Empty; - byte b = reader.ReadByte(); - if (b == 0xFF && reader.Position == reader.Length) - return null; - reader.Position--; - Debug.Assert((reader.BytesLeft & 1) == 0); - return reader.ReadUtf16String((int)(reader.BytesLeft / 2)); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs b/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs deleted file mode 100644 index e39bd50..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/LocalConstantSigBlobWriter.cs +++ /dev/null @@ -1,311 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Text; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet.Pdb.Portable { - readonly 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, DataWriter writer, TypeSig type, object value) { - var sigWriter = new LocalConstantSigBlobWriter(helper, systemMetadata); - sigWriter.Write(writer, type, value); - } - - void Write(DataWriter writer, TypeSig type, object value) { - for (; ; type = type.Next) { - if (type is null) - return; - - var et = type.ElementType; - writer.WriteByte((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.WriteSingle((float)value); - else { - helper.Error("Expected a Single constant"); - writer.WriteSingle(0); - } - return; - - case ElementType.R8: - if (value is double) - writer.WriteDouble((double)value); - else { - helper.Error("Expected a Double constant"); - writer.WriteDouble(0); - } - return; - - case ElementType.String: - if (value is null) - writer.WriteByte((byte)0xFF); - else if (value is string) - writer.WriteBytes(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 is null) - 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()) { - 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.Position--; - writer.WriteByte((byte)underlyingType.GetElementType()); - WritePrimitiveValue(writer, underlyingType.GetElementType(), value); - WriteTypeDefOrRef(writer, tdr); - return; - default: - helper.Error("Invalid enum underlying type"); - return; - } - } - else { - WriteTypeDefOrRef(writer, tdr); - bool valueWritten = false; - 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); - 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.WriteBytes(new byte[13]); - } - valueWritten = true; - } - else if (name == stringDateTime) { - if (value is DateTime) - writer.WriteInt64(((DateTime)value).Ticks); - else { - helper.Error("Expected a DateTime constant"); - writer.WriteInt64(0); - } - valueWritten = true; - } - } - if (!valueWritten) { - if (value is byte[]) - writer.WriteBytes((byte[])value); - else if (value is not null) { - helper.Error2("Unsupported constant: {0}.", value.GetType().FullName); - return; - } - } - } - return; - - case ElementType.Class: - WriteTypeDefOrRef(writer, ((ClassSig)type).TypeDefOrRef); - if (value is byte[]) - writer.WriteBytes((byte[])value); - else if (value is not 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.Error2("Unsupported element type in LocalConstant sig blob: {0}.", et); - 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) { - if (tdr is TypeRef tr) { - @namespace = tr.Namespace; - name = tr.Name; - return true; - } - - if (tdr is TypeDef td) { - @namespace = td.Namespace; - name = td.Name; - return true; - } - - @namespace = null; - name = null; - return false; - } - - void WritePrimitiveValue(DataWriter writer, ElementType et, object value) { - switch (et) { - case ElementType.Boolean: - if (value is bool) - writer.WriteBoolean((bool)value); - else { - helper.Error("Expected a Boolean constant"); - writer.WriteBoolean(false); - } - break; - - case ElementType.Char: - if (value is char) - writer.WriteUInt16((char)value); - else { - helper.Error("Expected a Char constant"); - writer.WriteUInt16(0); - } - break; - - case ElementType.I1: - if (value is sbyte) - writer.WriteSByte((sbyte)value); - else { - helper.Error("Expected a SByte constant"); - writer.WriteSByte(0); - } - break; - - case ElementType.U1: - if (value is byte) - writer.WriteByte((byte)value); - else { - helper.Error("Expected a Byte constant"); - writer.WriteByte(0); - } - break; - - case ElementType.I2: - if (value is short) - writer.WriteInt16((short)value); - else { - helper.Error("Expected an Int16 constant"); - writer.WriteInt16(0); - } - break; - - case ElementType.U2: - if (value is ushort) - writer.WriteUInt16((ushort)value); - else { - helper.Error("Expected a UInt16 constant"); - writer.WriteUInt16(0); - } - break; - - case ElementType.I4: - if (value is int) - writer.WriteInt32((int)value); - else { - helper.Error("Expected an Int32 constant"); - writer.WriteInt32(0); - } - break; - - case ElementType.U4: - if (value is uint) - writer.WriteUInt32((uint)value); - else { - helper.Error("Expected a UInt32 constant"); - writer.WriteUInt32(0); - } - break; - - case ElementType.I8: - if (value is long) - writer.WriteInt64((long)value); - else { - helper.Error("Expected an Int64 constant"); - writer.WriteInt64(0); - } - break; - - case ElementType.U8: - if (value is ulong) - writer.WriteUInt64((ulong)value); - else { - helper.Error("Expected a UInt64 constant"); - writer.WriteUInt64(0); - } - break; - - default: - throw new InvalidOperationException(); - } - } - - 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; - } - writer.WriteCompressedUInt32(codedToken); - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs b/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs deleted file mode 100644 index d110ab9..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoReader.cs +++ /dev/null @@ -1,305 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -// 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; -using dnlib.DotNet.MD; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb.Portable { - struct PortablePdbCustomDebugInfoReader { - public static PdbCustomDebugInfo Read(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, Guid kind, ref DataReader reader) { - try { - var cdiReader = new PortablePdbCustomDebugInfoReader(module, typeOpt, bodyOpt, gpContext, ref reader); - var cdi = cdiReader.Read(kind); - Debug.Assert(cdiReader.reader.Position == cdiReader.reader.Length); - return cdi; - } - catch (ArgumentException) { - } - catch (OutOfMemoryException) { - } - catch (IOException) { - } - return null; - } - - readonly ModuleDef module; - readonly TypeDef typeOpt; - readonly CilBody bodyOpt; - readonly GenericParamContext gpContext; - DataReader reader; - - PortablePdbCustomDebugInfoReader(ModuleDef module, TypeDef typeOpt, CilBody bodyOpt, GenericParamContext gpContext, ref DataReader 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(); - if (kind == CustomDebugInfoGuids.CompilationMetadataReferences) - return ReadCompilationMetadataReferences(); - if (kind == CustomDebugInfoGuids.CompilationOptions) - return ReadCompilationOptions(); - if (kind == CustomDebugInfoGuids.TypeDefinitionDocuments) - return ReadTypeDefinitionDocuments(); - if (kind == CustomDebugInfoGuids.EncStateMachineStateMap) - return ReadEncStateMachineStateMap(); - if (kind == CustomDebugInfoGuids.PrimaryConstructorInformationBlob) - return ReadPrimaryConstructorInformationBlob(); - Debug.Fail($"Unknown custom debug info guid: {kind}"); - return new PdbUnknownCustomDebugInfo(kind, reader.ReadRemainingBytes()); - } - - PdbCustomDebugInfo ReadAsyncMethodSteppingInformationBlob() { - if (bodyOpt is null) - return null; - uint catchHandlerOffset = reader.ReadUInt32() - 1; - Instruction catchHandler; - if (catchHandlerOffset == uint.MaxValue) - catchHandler = null; - else { - catchHandler = GetInstruction(catchHandlerOffset); - Debug.Assert(catchHandler is not 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 is not 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 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 not null); - if (moveNextMethod is null) - return null; - resumeInstr = GetInstruction(moveNextMethod, resumeOffset); - } - Debug.Assert(resumeInstr is not null); - if (resumeInstr is null) - return null; - asyncInfo.AsyncStepInfos.Add(new PdbAsyncStepInfo(yieldInstr, moveNextMethod, resumeInstr)); - } - return asyncInfo; - } - - PdbCustomDebugInfo ReadDefaultNamespace() { - var defaultNs = reader.ReadUtf8String((int)reader.BytesLeft); - 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() => 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() => new PdbSourceLinkCustomDebugInfo(reader.ReadRemainingBytes()); - - PdbCustomDebugInfo ReadStateMachineHoistedLocalScopes() { - if (bodyOpt is 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 is not null); - if (start is 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; - return reader.TryReadZeroTerminatedUtf8String(); - } - - PdbCustomDebugInfo ReadCompilationMetadataReferences() { - var cdi = new PdbCompilationMetadataReferencesCustomDebugInfo(); - - while (reader.BytesLeft > 0) { - var name = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(name is not null); - if (name is null) - break; - var aliases = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(aliases is not 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 not null); - if (key is null) - break; - var value = reader.TryReadZeroTerminatedUtf8String(); - Debug.Assert(value is not null); - if (value is null) - break; - cdi.Options.Add(new KeyValuePair(key, value)); - } - - return cdi; - } - - PdbCustomDebugInfo ReadTypeDefinitionDocuments() { - var docList = new List(); - while (reader.BytesLeft > 0) - docList.Add(new MDToken(Table.Document, reader.ReadCompressedUInt32())); - - return new PdbTypeDefinitionDocumentsDebugInfoMD(module, docList); - } - - 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; - } - - PdbCustomDebugInfo ReadPrimaryConstructorInformationBlob() => - new PrimaryConstructorInformationBlobDebugInfo(reader.ReadRemainingBytes()); - - 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 is null) - return null; - var body = method.Body; - if (body is 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/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs b/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs deleted file mode 100644 index 27e1431..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbCustomDebugInfoWriter.cs +++ /dev/null @@ -1,364 +0,0 @@ -// 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; - -namespace dnlib.DotNet.Pdb.Portable { - interface IPortablePdbCustomDebugInfoWriterHelper : IWriterError { - } - - readonly struct PortablePdbCustomDebugInfoWriter { - readonly IPortablePdbCustomDebugInfoWriterHelper helper; - readonly SerializerMethodContext methodContext; - readonly Metadata systemMetadata; - readonly MemoryStream outStream; - readonly DataWriter writer; - - 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, DataWriterContext context) { - this.helper = helper; - this.methodContext = methodContext; - this.systemMetadata = systemMetadata; - outStream = context.OutStream; - 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: - case PdbCustomDebugInfoKind.SourceServer: - 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; - - case PdbCustomDebugInfoKind.CompilationMetadataReferences: - WriteCompilationMetadataReferences((PdbCompilationMetadataReferencesCustomDebugInfo)cdi); - break; - - case PdbCustomDebugInfoKind.CompilationOptions: - WriteCompilationOptions((PdbCompilationOptionsCustomDebugInfo)cdi); - break; - - case PdbCustomDebugInfoKind.TypeDefinitionDocuments: - WriteTypeDefinitionDocuments((PdbTypeDefinitionDocumentsDebugInfo)cdi); - break; - - case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: - WriteEditAndContinueStateMachineStateMap((PdbEditAndContinueStateMachineStateMapDebugInfo)cdi); - break; - - case PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob: - WritePrimaryConstructorInformationBlob((PrimaryConstructorInformationBlobDebugInfo)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); - } - - void WriteStateMachineHoistedLocalScopes(PdbStateMachineHoistedLocalScopesCustomDebugInfo cdi) { - if (!methodContext.HasBody) { - helper.Error2("Method has no body, can't write custom debug info: {0}.", cdi.Kind); - return; - } - 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; - endOffset = 0; - } - else { - var startInstr = scope.Start; - if (startInstr is 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.WriteUInt32(startOffset); - writer.WriteUInt32(endOffset - startOffset); - } - } - - void WriteEditAndContinueLocalSlotMap(PdbEditAndContinueLocalSlotMapCustomDebugInfo cdi) { - var d = cdi.Data; - if (d is null) { - helper.Error("Data blob is null"); - return; - } - writer.WriteBytes(d); - } - - void WriteEditAndContinueLambdaMap(PdbEditAndContinueLambdaMapCustomDebugInfo cdi) { - var d = cdi.Data; - if (d is null) { - helper.Error("Data blob is null"); - return; - } - writer.WriteBytes(d); - } - - void WriteUnknown(PdbUnknownCustomDebugInfo cdi) { - var d = cdi.Data; - if (d is null) { - helper.Error("Data blob is null"); - return; - } - writer.WriteBytes(d); - } - - void WriteTupleElementNames(PortablePdbTupleElementNamesCustomDebugInfo cdi) { - var cdiNames = cdi.Names; - int count = cdiNames.Count; - for (int i = 0; i < count; i++) { - var name = cdiNames[i]; - if (name is null) { - helper.Error("Tuple name is null"); - return; - } - WriteUTF8Z(name); - } - } - - void WriteDefaultNamespace(PdbDefaultNamespaceCustomDebugInfo cdi) { - var ns = cdi.Namespace; - if (ns is null) { - helper.Error("Default namespace is null"); - return; - } - var bytes = Encoding.UTF8.GetBytes(ns); - writer.WriteBytes(bytes); - } - - void WriteDynamicLocalVariables(PdbDynamicLocalVariablesCustomDebugInfo cdi) { - var flags = cdi.Flags; - for (int i = 0; i < flags.Length; i += 8) - writer.WriteByte(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 is null) { - helper.Error("Source code blob is null"); - return; - } - writer.WriteBytes(d); - } - - void WriteSourceLink(PdbSourceLinkCustomDebugInfo cdi) { - var d = cdi.FileBlob; - if (d is null) { - helper.Error("Source link blob is null"); - return; - } - writer.WriteBytes(d); - } - - void WriteAsyncMethodSteppingInformation(PdbAsyncMethodCustomDebugInfo cdi) { - if (!methodContext.HasBody) { - helper.Error2("Method has no body, can't write custom debug info: {0}.", cdi.Kind); - return; - } - - uint catchHandlerOffset; - if (cdi.CatchHandlerInstruction is null) - catchHandlerOffset = 0; - else - catchHandlerOffset = methodContext.GetOffset(cdi.CatchHandlerInstruction) + 1; - writer.WriteUInt32(catchHandlerOffset); - - var cdiStepInfos = cdi.StepInfos; - int count = cdiStepInfos.Count; - for (int i = 0; i < count; i++) { - var info = cdiStepInfos[i]; - if (info.YieldInstruction is null) { - helper.Error("YieldInstruction is null"); - return; - } - if (info.BreakpointMethod is null) { - helper.Error("BreakpointMethod is null"); - return; - } - if (info.BreakpointInstruction is 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.WriteUInt32(yieldOffset); - writer.WriteUInt32(resumeOffset); - writer.WriteCompressedUInt32(resumeMethodRid); - } - } - - uint GetOffsetSlow(MethodDef method, Instruction instr) { - var body = method.Body; - if (body is 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; - } - - 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); - } - } - - void WriteTypeDefinitionDocuments(PdbTypeDefinitionDocumentsDebugInfo cdi) { - foreach (var document in cdi.Documents) - writer.WriteCompressedUInt32(systemMetadata.GetRid(document)); - } - - 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)); - } - } - - 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/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbReader.cs b/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbReader.cs deleted file mode 100644 index a024540..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/PortablePdbReader.cs +++ /dev/null @@ -1,396 +0,0 @@ -// 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.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 PdbFileKind pdbFileKind; - ModuleDef module; - readonly Metadata pdbMetadata; - SymbolDocument[] documents; - - public override PdbFileKind PdbFileKind => pdbFileKind; - public override int UserEntryPoint => pdbMetadata.PdbStream.EntryPoint.ToInt32(); - public override IList Documents => documents; - - public PortablePdbReader(DataReaderFactory pdbStream, PdbFileKind pdbFileKind) { - this.pdbFileKind = pdbFileKind; - pdbMetadata = MetadataFactory.CreateStandalonePortablePDB(pdbStream, true); - } - - internal bool MatchesModule(Guid pdbGuid, uint timestamp, uint age) { - 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; - if (age != 1) - return false; - - return true; - } - return false; - } - - public override void Initialize(ModuleDef module) { - this.module = module; - documents = ReadDocuments(); - } - - static Guid GetLanguageVendor(Guid language) { - if (language == PdbDocumentConstants.LanguageCSharp || language == PdbDocumentConstants.LanguageVisualBasic || language == PdbDocumentConstants.LanguageFSharp) - return PdbDocumentConstants.LanguageVendorMicrosoft; - return Guid.Empty; - } - - SymbolDocument[] ReadDocuments() { - Debug.Assert(module is not 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 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; - var languageVendor = GetLanguageVendor(language); - var documentType = PdbDocumentConstants.DocumentTypeText; - var checkSumAlgorithmId = pdbMetadata.GuidStream.Read(row.HashAlgorithm) ?? Guid.Empty; - var checkSum = pdbMetadata.BlobStream.ReadNoNull(row.Hash); - - 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, mdToken); - } - ListCache.Free(ref custInfos); - return docs; - } - - 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:X6}"); - document = null; - return false; - } - document = documents[index]; - return true; - } - - 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)) - return null; - - var sequencePoints = ReadSequencePoints(methodRid) ?? Array2.Empty(); - var gpContext = GenericParamContext.Create(method); - var rootScope = ReadScope(methodRid, gpContext); - - var kickoffMethod = GetKickoffMethod(methodRid); - var symbolMethod = new SymbolMethodImpl(this, method.MDToken.ToInt32(), rootScope, sequencePoints, kickoffMethod); - rootScope.method = symbolMethod; - return symbolMethod; - } - - int GetKickoffMethod(uint methodRid) { - uint rid = pdbMetadata.GetStateMachineMethodRid(methodRid); - if (rid == 0) - return 0; - if (!pdbMetadata.TablesStream.TryReadStateMachineMethodRow(rid, out var row)) - return 0; - return 0x06000000 + (int)row.KickoffMethod; - } - - SymbolSequencePoint[] ReadSequencePoints(uint methodRid) { - if (!pdbMetadata.TablesStream.MethodDebugInformationTable.IsValidRID(methodRid)) - return null; - if (!pdbMetadata.TablesStream.TryReadMethodDebugInformationRow(methodRid, out var row)) - return null; - if (row.SequencePoints == 0) - return null; - uint documentRid = row.Document; - - if (!pdbMetadata.BlobStream.TryCreateReader(row.SequencePoints, out var seqPointsReader)) - return null; - var seqPointsBuilder = ListCache.AllocList(); - uint localSig = seqPointsReader.ReadCompressedUInt32(); - if (documentRid == 0) - documentRid = seqPointsReader.ReadCompressedUInt32(); - - TryGetSymbolDocument(documentRid, out var document); - - uint ilOffset = uint.MaxValue; - int line = -1, column = 0; - bool canReadDocumentRecord = false; - while (seqPointsReader.Position < seqPointsReader.Length) { - uint data = seqPointsReader.ReadCompressedUInt32(); - if (data == 0 && canReadDocumentRecord) { - // document-record - - documentRid = seqPointsReader.ReadCompressedUInt32(); - TryGetSymbolDocument(documentRid, out document); - } - else { - // SequencePointRecord - - Debug.Assert(document is not null); - if (document is 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 = seqPointsReader.ReadCompressedUInt32(); - int dcolumns = dlines == 0 ? (int)seqPointsReader.ReadCompressedUInt32() : seqPointsReader.ReadCompressedInt32(); - - if (dlines == 0 && dcolumns == 0) { - // hidden-sequence-point-record - - symSeqPoint.Line = SequencePointConstants.HIDDEN_LINE; - symSeqPoint.EndLine = SequencePointConstants.HIDDEN_LINE; - symSeqPoint.Column = SequencePointConstants.HIDDEN_COLUMN; - symSeqPoint.EndColumn = SequencePointConstants.HIDDEN_COLUMN; - } - else { - // sequence-point-record - - if (line < 0) { - line = (int)seqPointsReader.ReadCompressedUInt32(); - column = (int)seqPointsReader.ReadCompressedUInt32(); - } - else { - line += seqPointsReader.ReadCompressedInt32(); - column += seqPointsReader.ReadCompressedInt32(); - } - - symSeqPoint.Line = line; - symSeqPoint.EndLine = line + (int)dlines; - symSeqPoint.Column = column; - symSeqPoint.EndColumn = column + dcolumns; - } - - seqPointsBuilder.Add(symSeqPoint); - } - - canReadDocumentRecord = true; - } - Debug.Assert(seqPointsReader.Position == seqPointsReader.Length); - - return ListCache.FreeAndToArray(ref seqPointsBuilder); - } - - 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]; - int token = new MDToken(Table.LocalScope, rid).ToInt32(); - bool b = pdbMetadata.TablesStream.TryReadLocalScopeRow(rid, out var row); - Debug.Assert(b); - uint startOffset = row.StartOffset; - uint endOffset = startOffset + row.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 is not 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 is null) - rootScopeOrNull = scope; - stack.Add(scope); - if (parent is not null) - parent.childrenList.Add(scope); - - scope.importScope = ReadPdbImportScope(ref importScopeBlobReader, row.ImportScope, gpContext); - ReadVariables(scope, gpContext, pdbMetadata.GetLocalVariableRidList(rid)); - ReadConstants(scope, pdbMetadata.GetLocalConstantRidList(rid)); - } - - ListCache.Free(ref stack); - ListCache.Free(ref custInfos); - } - return rootScopeOrNull ?? new SymbolScopeImpl(this, null, 0, int.MaxValue, Array2.Empty()); - } - - PdbImportScope ReadPdbImportScope(ref ImportScopeBlobReader importScopeBlobReader, uint importScope, GenericParamContext gpContext) { - 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; - int token = new MDToken(Table.ImportScope, importScope).ToInt32(); - if (!pdbMetadata.TablesStream.TryReadImportScopeRow(importScope, out var row)) - return null; - var scope = new PdbImportScope(); - GetCustomDebugInfos(token, gpContext, scope.CustomDebugInfos); - if (result is null) - result = scope; - if (prevScope is not null) - prevScope.Parent = scope; - importScopeBlobReader.Read(row.Imports, scope.Imports); - prevScope = scope; - importScope = row.Parent; - } - - return result; - } - - void ReadVariables(SymbolScopeImpl scope, GenericParamContext gpContext, RidList rids) { - if (rids.Count == 0) - return; - var table = pdbMetadata.TablesStream.LocalVariableTable; - var custInfos = ListCache.AllocList(); - 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); - var customDebugInfos = custInfos.Count == 0 ? Array2.Empty() : custInfos.ToArray(); - bool b = pdbMetadata.TablesStream.TryReadLocalVariableRow(rid, out var row); - Debug.Assert(b); - var name = pdbMetadata.StringsStream.Read(row.Name); - scope.localsList.Add(new SymbolVariableImpl(name, ToSymbolVariableAttributes(row.Attributes), row.Index, customDebugInfos)); - } - ListCache.Free(ref custInfos); - } - - static PdbLocalAttributes ToSymbolVariableAttributes(ushort attributes) { - var res = PdbLocalAttributes.None; - const ushort DebuggerHidden = 0x0001; - if ((attributes & DebuggerHidden) != 0) - res |= PdbLocalAttributes.DebuggerHidden; - return res; - } - - void ReadConstants(SymbolScopeImpl scope, RidList rids) { - if (rids.Count == 0) - return; - scope.SetConstants(pdbMetadata, rids); - } - - 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 not null) { - var asyncMethod = TryCreateAsyncMethod(module, symMethod.KickoffMethod, asyncStepInfo.AsyncStepInfos, asyncStepInfo.CatchHandler); - 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 not null); - if (iteratorMethod is not 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; - int count = asyncStepInfos.Count; - for (int i = 0; i < count; i++) - asyncMethod.StepInfos.Add(asyncStepInfos[i]); - 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, out var asyncStepInfo); - Debug.Assert(asyncStepInfo is null); - } - - 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) - return; - var typeOpt = methodOpt?.DeclaringType; - for (int i = 0; i < ridList.Count; i++) { - var rid = ridList[i]; - if (!pdbMetadata.TablesStream.TryReadCustomDebugInformationRow(rid, out var row)) - continue; - var guid = pdbMetadata.GuidStream.Read(row.Kind); - if (!pdbMetadata.BlobStream.TryCreateReader(row.Value, out var reader)) - continue; - Debug.Assert(guid is not null); - if (guid is null) - continue; - var cdi = PortablePdbCustomDebugInfoReader.Read(module, typeOpt, bodyOpt, gpContext, guid.Value, ref reader); - Debug.Assert(cdi is not null); - if (cdi is not null) { - if (cdi is PdbAsyncMethodSteppingInformationCustomDebugInfo asyncStepInfoTmp) { - Debug.Assert(asyncStepInfo is null); - asyncStepInfo = asyncStepInfoTmp; - } - else - result.Add(cdi); - } - } - } - - public override void Dispose() => pdbMetadata.Dispose(); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/SequencePointConstants.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SequencePointConstants.cs deleted file mode 100644 index 23aa543..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SequencePointConstants.cs +++ /dev/null @@ -1,8 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/Portable/SymbolDocumentImpl.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SymbolDocumentImpl.cs deleted file mode 100644 index dce64fb..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolDocumentImpl.cs +++ /dev/null @@ -1,62 +0,0 @@ -// 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; - readonly PdbCustomDebugInfo[] customDebugInfos; - MDToken mdToken; - - string GetDebuggerString() { - var sb = new StringBuilder(); - if (language == PdbDocumentConstants.LanguageCSharp) - sb.Append("C#"); - else if (language == PdbDocumentConstants.LanguageVisualBasic) - sb.Append("VB"); - else if (language == PdbDocumentConstants.LanguageFSharp) - sb.Append("F#"); - else - sb.Append(language.ToString()); - sb.Append(", "); - if (checkSumAlgorithmId == PdbDocumentConstants.HashSHA1) - sb.Append("SHA-1"); - else if (checkSumAlgorithmId == PdbDocumentConstants.HashSHA256) - sb.Append("SHA-256"); - else - sb.Append(checkSumAlgorithmId.ToString()); - sb.Append(": "); - sb.Append(url); - return sb.ToString(); - } - - 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 override MDToken? MDToken => mdToken; - - 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; - this.documentType = documentType; - this.checkSumAlgorithmId = checkSumAlgorithmId; - this.checkSum = checkSum; - this.customDebugInfos = customDebugInfos; - this.mdToken = mdToken; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolMethodImpl.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SymbolMethodImpl.cs deleted file mode 100644 index 933d326..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolMethodImpl.cs +++ /dev/null @@ -1,31 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Pdb.Symbols; - -namespace dnlib.DotNet.Pdb.Portable { - sealed class SymbolMethodImpl : SymbolMethod { - readonly PortablePdbReader reader; - readonly int token; - readonly SymbolScope rootScope; - readonly SymbolSequencePoint[] sequencePoints; - readonly int 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; - this.token = token; - this.rootScope = rootScope; - this.sequencePoints = sequencePoints; - this.kickoffMethod = kickoffMethod; - } - - public override void GetCustomDebugInfos(MethodDef method, CilBody body, IList result) => - reader.GetCustomDebugInfos(this, method, body, result); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolReaderFactory.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SymbolReaderFactory.cs deleted file mode 100644 index af31b79..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolReaderFactory.cs +++ /dev/null @@ -1,91 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; -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 SymbolReaderFactory { - public static SymbolReader TryCreate(PdbReaderContext pdbContext, DataReaderFactory pdbStream, bool isEmbeddedPortablePdb) { - bool disposePdbStream = true; - try { - if (!pdbContext.HasDebugInfo) - return null; - if (pdbStream is null) - return null; - if (pdbStream.Length < 4) - return null; - if (pdbStream.CreateReader().ReadUInt32() != 0x424A5342) - return null; - - var debugDir = pdbContext.CodeViewDebugDirectory; - if (debugDir is null) - 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; - - var reader = new PortablePdbReader(pdbStream, isEmbeddedPortablePdb ? PdbFileKind.EmbeddedPortablePDB : PdbFileKind.PortablePDB); - if (!reader.MatchesModule(pdbGuid, debugDir.TimeDateStamp, age)) - return null; - disposePdbStream = false; - return reader; - } - catch (IOException) { - } - finally { - if (disposePdbStream) - pdbStream?.Dispose(); - } - return null; - } - - public static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata) { - if (metadata is null) - return null; - try { - if (!pdbContext.HasDebugInfo) - return null; - var embeddedDir = pdbContext.TryGetDebugDirectoryEntry(ImageDebugType.EmbeddedPortablePdb); - if (embeddedDir is null) - return null; - var reader = pdbContext.CreateReader(embeddedDir.AddressOfRawData, embeddedDir.SizeOfData); - if (reader.Length < 8) - return null; - // "MPDB" = 0x4244504D - if (reader.ReadUInt32() != 0x4244504D) - return null; - uint uncompressedSize = reader.ReadUInt32(); - // 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(reader.AsStream(), 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 = ByteArrayDataReaderFactory.Create(decompressedBytes, filename: null); - return TryCreate(pdbContext, stream, isEmbeddedPortablePdb: true); - } - } - catch (IOException) { - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolScopeImpl.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SymbolScopeImpl.cs deleted file mode 100644 index cc90eeb..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolScopeImpl.cs +++ /dev/null @@ -1,93 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -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; - internal readonly List childrenList; - internal readonly List localsList; - internal PdbImportScope importScope; - readonly PdbCustomDebugInfo[] customDebugInfos; - - public override SymbolMethod Method { - get { - if (method is not null) - return method; - var p = parent; - if (p is null) - return method; - for (;;) { - if (p.parent is null) - return method = p.method; - p = p.parent; - } - } - } - - 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 => Array2.Empty(); - 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; - method = null; - this.parent = parent; - this.startOffset = startOffset; - this.endOffset = endOffset; - childrenList = new List(); - localsList = new List(); - this.customDebugInfos = customDebugInfos; - } - - Metadata constantsMetadata; - RidList constantRidList; - - internal void SetConstants(Metadata metadata, RidList rids) { - constantsMetadata = metadata; - constantRidList = rids; - } - - public override IList GetConstants(ModuleDef module, GenericParamContext gpContext) { - if (constantRidList.Count == 0) - return Array2.Empty(); - Debug.Assert(constantsMetadata is not null); - - var res = new PdbConstant[constantRidList.Count]; - int w = 0; - for (int i = 0; i < res.Length; i++) { - uint rid = constantRidList[i]; - bool b = constantsMetadata.TablesStream.TryReadLocalConstantRow(rid, out var row); - Debug.Assert(b); - var name = constantsMetadata.StringsStream.Read(row.Name); - if (!constantsMetadata.BlobStream.TryCreateReader(row.Signature, out var reader)) - continue; - var localConstantSigBlobReader = new LocalConstantSigBlobReader(module, ref reader, gpContext); - b = localConstantSigBlobReader.Read(out var type, out object value); - Debug.Assert(b); - 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; - } - } - if (res.Length != w) - Array.Resize(ref res, w); - return res; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolVariableImpl.cs b/Plugins/dnlib/DotNet/Pdb/Portable/SymbolVariableImpl.cs deleted file mode 100644 index 111c35a..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Portable/SymbolVariableImpl.cs +++ /dev/null @@ -1,24 +0,0 @@ -// 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 PdbLocalAttributes attributes; - readonly int index; - readonly PdbCustomDebugInfo[] 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; - this.attributes = attributes; - this.index = index; - this.customDebugInfos = customDebugInfos; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/SequencePoint.cs b/Plugins/dnlib/DotNet/Pdb/SequencePoint.cs deleted file mode 100644 index 916c249..0000000 --- a/Plugins/dnlib/DotNet/Pdb/SequencePoint.cs +++ /dev/null @@ -1,50 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; - -namespace dnlib.DotNet.Pdb { - /// - /// PDB sequence point - /// - [DebuggerDisplay("({StartLine}, {StartColumn}) - ({EndLine}, {EndColumn}) {Document.Url}")] - public sealed class SequencePoint { - /// - /// PDB document - /// - public PdbDocument Document { get; set; } - - /// - /// Start line - /// - public int StartLine { get; set; } - - /// - /// Start column - /// - public int StartColumn { get; set; } - - /// - /// End line - /// - public int EndLine { get; set; } - - /// - /// End column - /// - public int EndColumn { get; set; } - - /// - /// Clones this instance - /// - /// A new cloned instance - public SequencePoint Clone() { - return new SequencePoint() { - Document = Document, - StartLine = StartLine, - StartColumn = StartColumn, - EndLine = EndLine, - EndColumn = EndColumn, - }; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/SymbolReaderFactory.cs b/Plugins/dnlib/DotNet/Pdb/SymbolReaderFactory.cs deleted file mode 100644 index b8aff57..0000000 --- a/Plugins/dnlib/DotNet/Pdb/SymbolReaderFactory.cs +++ /dev/null @@ -1,149 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Text; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb.Symbols; -using dnlib.IO; - -namespace dnlib.DotNet.Pdb { - static class SymbolReaderFactory { - 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; - - 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); - } - static readonly char[] windowsPathSepChars = new char[] { '\\', '/' }; - - public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, string pdbFileName) { - var pdbContext = new PdbReaderContext(metadata.PEImage, options); - if (!pdbContext.HasDebugInfo) - return null; - return CreateCore(pdbContext, metadata, DataReaderFactoryUtils.TryCreateDataReaderFactory(pdbFileName)); - } - - 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)); - } - - public static SymbolReader Create(PdbReaderOptions options, Metadata metadata, DataReaderFactory pdbStream) { - var pdbContext = new PdbReaderContext(metadata.PEImage, options); - return CreateCore(pdbContext, metadata, pdbStream); - } - - static SymbolReader CreateCore(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { - SymbolReader symReader = null; - bool error = true; - try { - if (!pdbContext.HasDebugInfo) - return null; - -#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); - - if (symReader is not null) { - error = false; - return symReader; - } - } - catch (IOException) { - } - finally { - if (error) { - pdbStream?.Dispose(); - symReader?.Dispose(); - } - } - return null; - } - - 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; - } - - public static SymbolReader TryCreateEmbeddedPdbReader(PdbReaderOptions options, Metadata metadata) { - var pdbContext = new PdbReaderContext(metadata.PEImage, options); - if (!pdbContext.HasDebugInfo) - return null; - return TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); - } - - static SymbolReader CreateManaged(PdbReaderContext pdbContext, Metadata metadata, DataReaderFactory pdbStream) { - try { - // Embedded PDBs have priority - var embeddedReader = TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); - if (embeddedReader is not null) { - pdbStream?.Dispose(); - return embeddedReader; - } - - return CreateManagedCore(pdbContext, pdbStream); - } - catch { - pdbStream?.Dispose(); - throw; - } - } - - static SymbolReader CreateManagedCore(PdbReaderContext pdbContext, DataReaderFactory pdbStream) { - if (pdbStream is null) - return null; - try { - var reader = pdbStream.CreateReader(); - if (reader.Length >= 4) { - uint sig = reader.ReadUInt32(); - if (sig == 0x424A5342) - return Portable.SymbolReaderFactory.TryCreate(pdbContext, pdbStream, isEmbeddedPortablePdb: false); - return Managed.SymbolReaderFactory.Create(pdbContext, pdbStream); - } - } - catch (IOException) { - } - pdbStream?.Dispose(); - return null; - } - - static SymbolReader TryCreateEmbeddedPortablePdbReader(PdbReaderContext pdbContext, Metadata metadata) => - Portable.SymbolReaderFactory.TryCreateEmbeddedPortablePdbReader(pdbContext, metadata); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs deleted file mode 100644 index 65c9a1c..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolAsyncStepInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolDocument.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolDocument.cs deleted file mode 100644 index 5850996..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolDocument.cs +++ /dev/null @@ -1,50 +0,0 @@ -// 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; } - - /// - /// Gets the custom debug infos - /// - public abstract PdbCustomDebugInfo[] CustomDebugInfos { get; } - - /// - /// Gets the Metadata token of the document if available. - /// - public abstract MDToken? MDToken { get; } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolMethod.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolMethod.cs deleted file mode 100644 index 801cfd9..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolMethod.cs +++ /dev/null @@ -1,34 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Emit; - -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 IList SequencePoints { get; } - - /// - /// Reads custom debug info - /// - /// Method - /// Method body - /// Updated with custom debug info - public abstract void GetCustomDebugInfos(MethodDef method, CilBody body, IList result); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolNamespace.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolNamespace.cs deleted file mode 100644 index a556b0f..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolNamespace.cs +++ /dev/null @@ -1,13 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolReader.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolReader.cs deleted file mode 100644 index 2cc995a..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolReader.cs +++ /dev/null @@ -1,54 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -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 PDB file kind - /// - public abstract PdbFileKind PdbFileKind { get; } - - /// - /// Gets the user entry point token or 0 if none - /// - public abstract int UserEntryPoint { get; } - - /// - /// Gets all documents - /// - public abstract IList Documents { get; } - - /// - /// Gets a method or returns null if the method doesn't exist in the PDB file - /// - /// Method - /// Edit and continue version. The first version is 1 - /// - public abstract SymbolMethod GetMethod(MethodDef method, int version); - - /// - /// 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 - /// - public virtual void Dispose() { - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolScope.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolScope.cs deleted file mode 100644 index b24b03f..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolScope.cs +++ /dev/null @@ -1,63 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -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 IList Children { get; } - - /// - /// Gets all locals defined in this scope - /// - public abstract IList Locals { get; } - - /// - /// Gets all namespaces in this scope - /// - public abstract IList Namespaces { get; } - - /// - /// Gets all custom debug infos - /// - public abstract IList CustomDebugInfos { 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 IList GetConstants(ModuleDef module, GenericParamContext gpContext); - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolSequencePoint.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolSequencePoint.cs deleted file mode 100644 index 45535e6..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolSequencePoint.cs +++ /dev/null @@ -1,62 +0,0 @@ -// 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 - /// - 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; - - readonly 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/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolVariable.cs b/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolVariable.cs deleted file mode 100644 index dc9eb64..0000000 --- a/Plugins/dnlib/DotNet/Pdb/Symbols/SymbolVariable.cs +++ /dev/null @@ -1,28 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb.Symbols { - /// - /// A variable - /// - public abstract class SymbolVariable { - /// - /// Gets the name - /// - public abstract string Name { get; } - - /// - /// Gets the attributes - /// - public abstract PdbLocalAttributes Attributes { get; } - - /// - /// Gets the index of the variable - /// - public abstract int Index { get; } - - /// - /// Gets all custom debug infos - /// - public abstract PdbCustomDebugInfo[] CustomDebugInfos { get; } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs deleted file mode 100644 index 5869ec5..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CorSymVarFlag.cs +++ /dev/null @@ -1,10 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet.Pdb.WindowsPdb { - [Flags] - enum CorSymVarFlag : uint { - VAR_IS_COMP_GEN = 0x00000001, - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs deleted file mode 100644 index d4aed7e..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/CustomDebugInfoConstants.cs +++ /dev/null @@ -1,8 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Pdb.WindowsPdb { - static class CustomDebugInfoConstants { - public const int Version = 4; - public const int RecordVersion = 4; - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs deleted file mode 100644 index 1a65864..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoReader.cs +++ /dev/null @@ -1,339 +0,0 @@ -// 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; - -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 { - /// - /// 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) { - try { - var reader = ByteArrayDataReaderFactory.CreateReader(data); - var cdiReader = new PdbCustomDebugInfoReader(method, body, ref reader); - cdiReader.Read(result); - } - catch (ArgumentException) { - } - catch (OutOfMemoryException) { - } - catch (IOException) { - } - } - - readonly ModuleDef module; - readonly TypeDef typeOpt; - readonly CilBody bodyOpt; - readonly GenericParamContext gpContext; - DataReader reader; - - PdbCustomDebugInfoReader(MethodDef method, CilBody body, ref DataReader reader) { - module = method.Module; - typeOpt = method.DeclaringType; - bodyOpt = body; - gpContext = GenericParamContext.Create(method); - this.reader = reader; - } - - void Read(IList result) { - 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.CanRead(8U)) { - 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 || (ulong)reader.Position - 8 + (uint)recSize > reader.Length) - return; - if (recKind <= PdbCustomDebugInfoKind.DynamicLocals) - alignmentSize = 0; - if (alignmentSize > 3) - return; - var nextRecPos = reader.Position - 8 + (uint)recSize; - - if (recVersion == CustomDebugInfoConstants.RecordVersion) { - ulong recPosEnd = (ulong)reader.Position - 8 + (uint)recSize - (uint)alignmentSize; - var cdi = ReadRecord(recKind, recPosEnd); - Debug.Assert(cdi is not null); - Debug.Assert(reader.Position <= recPosEnd); - if (reader.Position > recPosEnd) - return; - if (cdi is not null) { - Debug.Assert(cdi.Kind == recKind); - result.Add(cdi); - } - } - - reader.Position = nextRecPos; - } - } - - PdbCustomDebugInfo ReadRecord(PdbCustomDebugInfoKind recKind, ulong 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 = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; - if (method is null) - return null; - return new PdbForwardMethodInfoCustomDebugInfo(method); - - case PdbCustomDebugInfoKind.ForwardModuleInfo: - method = module.ResolveToken(reader.ReadUInt32(), gpContext) as IMethodDefOrRef; - if (method is null) - return null; - return new PdbForwardModuleInfoCustomDebugInfo(method); - - case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: - if (bodyOpt is null) - return null; - count = reader.ReadInt32(); - if (count < 0) - return null; - var smScope = new PdbStateMachineHoistedLocalScopesCustomDebugInfo(count); - 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 is null) - return null; - smScope.Scopes.Add(new StateMachineHoistedLocalScope(start, end)); - } - } - return smScope; - - case PdbCustomDebugInfoKind.StateMachineTypeName: - var name = ReadUnicodeZ(recPosEnd, needZeroChar: true); - if (name is null) - return null; - var type = GetNestedType(name); - if (type is null) - return null; - return new PdbStateMachineTypeNameCustomDebugInfo(type); - - case PdbCustomDebugInfoKind.DynamicLocals: - if (bodyOpt is null) - return null; - count = reader.ReadInt32(); - const int dynLocalRecSize = 64 + 4 + 4 + 2 * 64; - if (reader.Position + (ulong)(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)bodyOpt.Variables.Count) - return null; - - var nameEndPos = reader.Position + 2 * 64; - name = ReadUnicodeZ(nameEndPos, needZeroChar: false); - reader.Position = nameEndPos; - - 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 not null && local.Name != name) - local = null; - if (local is not 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: - if (bodyOpt is null) - return null; - 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 is null) - return null; - tupleInfo.TupleElementNames.Add(s); - } - - localIndex = reader.ReadInt32(); - uint scopeStart = reader.ReadUInt32(); - uint scopeEnd = reader.ReadUInt32(); - name = ReadUTF8Z(recPosEnd); - if (name is 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 is null) - return null; - } - else { - if ((uint)localIndex >= (uint)bodyOpt.Variables.Count) - return null; - local = bodyOpt.Variables[localIndex]; - } - - if (local is not 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:X}"); - data = reader.ReadBytes((int)(recPosEnd - reader.Position)); - return new PdbUnknownCustomDebugInfo(recKind, data); - } - } - - TypeDef GetNestedType(string name) { - if (typeOpt is null) - return null; - 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 index = name.Length; - if (typeName[index] == '`') { - Debug.Assert(index + 1 < typeName.Length); - bool ok = true; - index++; - while (index < typeName.Length) { - if (!char.IsDigit(typeName[index])) { - ok = false; - break; - } - index++; - } - if (ok) - return type; - } - } - } - } - return null; - } - - string ReadUnicodeZ(ulong recPosEnd, bool needZeroChar) { - var sb = new StringBuilder(); - - for (;;) { - if (reader.Position >= recPosEnd) - return needZeroChar ? null : sb.ToString(); - var c = reader.ReadChar(); - if (c == 0) - return sb.ToString(); - sb.Append(c); - } - } - - string ReadUTF8Z(ulong recPosEnd) { - if (reader.Position > recPosEnd) - return null; - return reader.TryReadZeroTerminatedUtf8String(); - } - - 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; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs deleted file mode 100644 index fbfe6cb..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PdbCustomDebugInfoWriter.cs +++ /dev/null @@ -1,399 +0,0 @@ -// 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.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Text; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet.Pdb.WindowsPdb { - sealed class PdbCustomDebugInfoWriterContext { - public ILogger Logger; - public readonly MemoryStream MemoryStream; - public readonly DataWriter Writer; - public readonly Dictionary InstructionToOffsetDict; - - public PdbCustomDebugInfoWriterContext() { - MemoryStream = new MemoryStream(); - Writer = new DataWriter(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 DataWriter 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; - logger = context.Logger; - memoryStream = context.MemoryStream; - writer = context.Writer; - instructionToOffsetDict = context.InstructionToOffsetDict; - bodySize = 0; - instructionToOffsetDictInitd = false; - memoryStream.SetLength(0); - memoryStream.Position = 0; - } - - void InitializeInstructionDictionary() { - Debug.Assert(!instructionToOffsetDictInitd); - instructionToOffsetDict.Clear(); - var body = method.Body; - if (body is 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 is null) { - if (nullIsEndOfMethod) - return bodySize; - Error("Instruction is null"); - return uint.MaxValue; - } - 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); - - 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.WriteByte(CustomDebugInfoConstants.Version); - writer.WriteByte((byte)customDebugInfos.Count); - writer.WriteUInt16(0); - - for (int i = 0; i < customDebugInfos.Count; i++) { - var info = customDebugInfos[i]; - if (info is 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.Position; - writer.WriteByte(CustomDebugInfoConstants.RecordVersion); - writer.WriteByte((byte)info.Kind); - writer.WriteUInt16(0); - writer.WriteUInt32(0); - - int count, j, k; - uint token; - switch (info.Kind) { - case PdbCustomDebugInfoKind.UsingGroups: - var usingRec = info as PdbUsingGroupsCustomDebugInfo; - if (usingRec is 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.WriteUInt16((ushort)count); - for (j = 0; j < count; j++) - writer.WriteUInt16(usingRec.UsingCounts[j]); - break; - - case PdbCustomDebugInfoKind.ForwardMethodInfo: - var fwdMethodRec = info as PdbForwardMethodInfoCustomDebugInfo; - if (fwdMethodRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - token = GetMethodToken(fwdMethodRec.Method); - if (token == 0) - return null; - writer.WriteUInt32(token); - break; - - case PdbCustomDebugInfoKind.ForwardModuleInfo: - var fwdModRec = info as PdbForwardModuleInfoCustomDebugInfo; - if (fwdModRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - token = GetMethodToken(fwdModRec.Method); - if (token == 0) - return null; - writer.WriteUInt32(token); - break; - - case PdbCustomDebugInfoKind.StateMachineHoistedLocalScopes: - var smLocalScopesRec = info as PdbStateMachineHoistedLocalScopesCustomDebugInfo; - if (smLocalScopesRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - count = smLocalScopesRec.Scopes.Count; - writer.WriteInt32(count); - for (j = 0; j < count; j++) { - var scope = smLocalScopesRec.Scopes[j]; - if (scope.IsSynthesizedLocal) { - writer.WriteInt32(0); - writer.WriteInt32(0); - } - else { - writer.WriteUInt32(GetInstructionOffset(scope.Start, nullIsEndOfMethod: false)); - writer.WriteUInt32(GetInstructionOffset(scope.End, nullIsEndOfMethod: true) - 1); - } - } - break; - - case PdbCustomDebugInfoKind.StateMachineTypeName: - var smTypeRec = info as PdbStateMachineTypeNameCustomDebugInfo; - if (smTypeRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - var type = smTypeRec.Type; - if (type is null) { - Error("State machine type is null"); - return null; - } - WriteUnicodeZ(MetadataNameToRoslynName(type.Name)); - break; - - case PdbCustomDebugInfoKind.DynamicLocals: - var dynLocListRec = info as PdbDynamicLocalsCustomDebugInfo; - if (dynLocListRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - count = dynLocListRec.Locals.Count; - writer.WriteInt32(count); - for (j = 0; j < count; j++) { - var dynLoc = dynLocListRec.Locals[j]; - if (dynLoc is 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 is 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.WriteByte(dynLoc.Flags[k]); - while (k++ < 64) - writer.WriteByte(0); - writer.WriteInt32(dynLoc.Flags.Count); - - if (dynLoc.Local is null) - writer.WriteInt32(0); - else - writer.WriteInt32(dynLoc.Local.Index); - - for (k = 0; k < name.Length; k++) - writer.WriteUInt16(name[k]); - while (k++ < 64) - writer.WriteUInt16(0); - } - break; - - case PdbCustomDebugInfoKind.EditAndContinueLocalSlotMap: - var encLocalMapRec = info as PdbEditAndContinueLocalSlotMapCustomDebugInfo; - if (encLocalMapRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - writer.WriteBytes(encLocalMapRec.Data); - break; - - case PdbCustomDebugInfoKind.EditAndContinueLambdaMap: - var encLambdaRec = info as PdbEditAndContinueLambdaMapCustomDebugInfo; - if (encLambdaRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - writer.WriteBytes(encLambdaRec.Data); - break; - - case PdbCustomDebugInfoKind.TupleElementNames: - var tupleListRec = info as PdbTupleElementNamesCustomDebugInfo; - if (tupleListRec is null) { - Error("Unsupported custom debug info type {0}", info.GetType()); - return null; - } - count = tupleListRec.Names.Count; - writer.WriteInt32(count); - for (j = 0; j < count; j++) { - var tupleInfo = tupleListRec.Names[j]; - if (tupleInfo is null) { - Error("Tuple name info is null"); - return null; - } - writer.WriteInt32(tupleInfo.TupleElementNames.Count); - for (k = 0; k < tupleInfo.TupleElementNames.Count; k++) - WriteUTF8Z(tupleInfo.TupleElementNames[k]); - - if (tupleInfo.Local is null) { - writer.WriteInt32(-1); - writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeStart, nullIsEndOfMethod: false)); - writer.WriteUInt32(GetInstructionOffset(tupleInfo.ScopeEnd, nullIsEndOfMethod: true)); - } - else { - writer.WriteInt32(tupleInfo.Local.Index); - writer.WriteInt64(0L); - } - WriteUTF8Z(tupleInfo.Name); - } - break; - - default: - var unkRec = info as PdbUnknownCustomDebugInfo; - if (unkRec is null) { - Error("Unsupported custom debug info class {0}", info.GetType()); - return null; - } - writer.WriteBytes(unkRec.Data); - break; - } - - 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.Position = recordPos + 3; - if (info.Kind <= PdbCustomDebugInfoKind.DynamicLocals) - writer.WriteByte(0); - else - writer.WriteByte((byte)(alignedLen - recLen)); - writer.WriteUInt32((uint)alignedLen); - - writer.Position = pos; - while (writer.Position < recordPos + alignedLen) - writer.WriteByte(0); - } - - return memoryStream.ToArray(); - } - - string MetadataNameToRoslynName(string name) { - if (name is null) - return name; - int index = name.LastIndexOf('`'); - if (index < 0) - return name; - return name.Substring(0, index); - } - - void WriteUnicodeZ(string s) { - if (s is 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.WriteUInt16(s[i]); - writer.WriteUInt16(0); - } - - void WriteUTF8Z(string s) { - if (s is null) { - Error("String is null"); - return; - } - - if (s.IndexOf('\0') >= 0) { - Error("String contains a NUL char: {0}", s); - return; - } - - writer.WriteBytes(Encoding.UTF8.GetBytes(s)); - writer.WriteByte(0); - } - - uint GetMethodToken(IMethodDefOrRef method) { - if (method is null) { - Error("Method is null"); - return 0; - } - - 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); - return 0; - } - return new MDToken(md.MDToken.Table, rid).Raw; - } - - if (method is MemberRef mr && mr.IsMethodRef) - return metadata.GetToken(mr).Raw; - - Error("Not a method"); - return 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs deleted file mode 100644 index 6bee81e..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/PseudoCustomDebugInfoFactory.cs +++ /dev/null @@ -1,77 +0,0 @@ -// 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 is not null) { - asyncMethod.CatchHandlerInstruction = GetInstruction(body, asyncCatchHandlerILOffset.Value); - 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 not null); - if (yieldInstruction is 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 is not null); - if (breakpointMethod is null) - continue; - breakpointInstruction = GetInstruction(breakpointMethod.Body, rawInfo.BreakpointOffset); - } - Debug.Assert(breakpointInstruction is not null); - if (breakpointInstruction is null) - continue; - - asyncMethod.StepInfos.Add(new PdbAsyncStepInfo(yieldInstruction, breakpointMethod, breakpointInstruction)); - } - - return asyncMethod; - } - - static Instruction GetInstruction(CilBody body, uint offset) { - if (body is 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/Plugins/dnlib/DotNet/Pdb/WindowsPdb/SymbolWriter.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/SymbolWriter.cs deleted file mode 100644 index 48fc59d..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/SymbolWriter.cs +++ /dev/null @@ -1,36 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs b/Plugins/dnlib/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs deleted file mode 100644 index 1d7336d..0000000 --- a/Plugins/dnlib/DotNet/Pdb/WindowsPdb/WindowsPdbWriter.cs +++ /dev/null @@ -1,444 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics.SymbolStore; -using dnlib.DotNet.Emit; -using dnlib.DotNet.Writer; - -namespace dnlib.DotNet.Pdb.WindowsPdb { - sealed class WindowsPdbWriter : IDisposable { - SymbolWriter writer; - 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; - readonly int localsEndScopeIncValue; - - public ILogger Logger { get; set; } - - public WindowsPdbWriter(SymbolWriter writer, PdbState pdbState, Metadata metadata) - : this(pdbState, metadata) { - if (pdbState is null) - throw new ArgumentNullException(nameof(pdbState)); - if (metadata is null) - throw new ArgumentNullException(nameof(metadata)); - this.writer = writer ?? throw new ArgumentNullException(nameof(writer)); - writer.Initialize(metadata); - } - - WindowsPdbWriter(PdbState pdbState, Metadata metadata) { - this.pdbState = pdbState; - this.metadata = metadata; - module = metadata.Module; - instrToOffset = new Dictionary(); - customDebugInfoWriterContext = new PdbCustomDebugInfoWriterContext(); - localsEndScopeIncValue = PdbUtils.IsEndInclusive(PdbFileKind.WindowsPDB, pdbState.Compiler) ? 1 : 0; - } - - ISymbolDocumentWriter Add(PdbDocument pdbDoc) { - 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); - 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(GetUserEntryPointToken()); - - var cdiBuilder = new List(); - foreach (var type in module.GetTypes()) { - 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 is null) - continue; - if (!ShouldAddMethod(method)) - continue; - 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) { - var body = method.Body; - if (body is null) - return false; - - if (body.HasPdbMethod) - return true; - - 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 is not null) - return true; - if (local.Attributes != 0) - return true; - } - - var bodyInstructions = body.Instructions; - count = bodyInstructions.Count; - for (int i = 0; i < count; i++) { - if (bodyInstructions[i].SequencePoint is not null) - return true; - } - - return false; - } - - sealed class SequencePointHelper { - readonly Dictionary checkedPdbDocs = new Dictionary(); - int[] instrOffsets = Array2.Empty(); - int[] startLines; - int[] startColumns; - int[] endLines; - int[] endColumns; - - public void Write(WindowsPdbWriter pdbWriter, IList instrs) { - checkedPdbDocs.Clear(); - while (true) { - PdbDocument currPdbDoc = null; - bool otherDocsAvailable = false; - int index = 0, instrOffset = 0; - Instruction instr = null; - for (int i = 0; i < instrs.Count; i++, instrOffset += instr.GetSize()) { - instr = instrs[i]; - var seqp = instr.SequencePoint; - if (seqp is null || seqp.Document is null) - continue; - if (checkedPdbDocs.ContainsKey(seqp.Document)) - continue; - if (currPdbDoc is null) - currPdbDoc = seqp.Document; - else if (currPdbDoc != seqp.Document) { - otherDocsAvailable = true; - continue; - } - - if (index >= instrOffsets.Length) { - int newSize = index * 2; - if (newSize < 64) - newSize = 64; - Array.Resize(ref instrOffsets, newSize); - Array.Resize(ref startLines, newSize); - Array.Resize(ref startColumns, newSize); - Array.Resize(ref endLines, newSize); - Array.Resize(ref endColumns, newSize); - } - - instrOffsets[index] = instrOffset; - startLines[index] = seqp.StartLine; - startColumns[index] = seqp.StartColumn; - endLines[index] = seqp.EndLine; - endColumns[index] = seqp.EndColumn; - index++; - } - if (index != 0) - pdbWriter.writer.DefineSequencePoints(pdbWriter.Add(currPdbDoc), (uint)index, instrOffsets, startLines, startColumns, endLines, endColumns); - - if (!otherDocsAvailable) - break; - if (currPdbDoc is not null) - checkedPdbDocs.Add(currPdbDoc, true); - } - } - } - - struct CurrentMethod { - readonly WindowsPdbWriter pdbWriter; - public readonly MethodDef Method; - readonly Dictionary toOffset; - public readonly uint BodySize; - - public CurrentMethod(WindowsPdbWriter pdbWriter, MethodDef method, Dictionary toOffset) { - this.pdbWriter = pdbWriter; - Method = method; - this.toOffset = toOffset; - toOffset.Clear(); - uint offset = 0; - var instructions = method.Body.Instructions; - int count = instructions.Count; - for (int i = 0; i < count; i++) { - var instr = instructions[i]; - toOffset[instr] = offset; - offset += (uint)instr.GetSize(); - } - BodySize = offset; - } - - public readonly int GetOffset(Instruction instr) { - if (instr is null) - return (int)BodySize; - if (toOffset.TryGetValue(instr, out uint 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, 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); - return; - } - - var info = new CurrentMethod(this, method, instrToOffset); - var body = method.Body; - var symbolToken = new MDToken(MD.Table.Method, rid); - writer.OpenMethod(symbolToken); - seqPointsHelper.Write(this, info.Method.Body.Instructions); - - var pdbMethod = body.PdbMethod; - if (pdbMethod is null) - body.PdbMethod = pdbMethod = new PdbMethod(); - var scope = pdbMethod.Scope; - 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) { - // 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 { - var scopes = scope.Scopes; - int count = scopes.Count; - for (int i = 0; i < count; i++) - WriteScope(ref info, scopes[i], 0); - } - } - else { - // C++/.NET (some methods) - WriteScope(ref info, scope, 0); - } - - GetPseudoCustomDebugInfos(method.CustomDebugInfos, cdiBuilder, out var asyncMethod); - if (cdiBuilder.Count != 0) { - customDebugInfoWriterContext.Logger = GetLogger(); - var cdiData = PdbCustomDebugInfoWriter.Write(metadata, method, customDebugInfoWriterContext, cdiBuilder); - if (cdiData is not null) - writer.SetSymAttribute(symbolToken, "MD2", cdiData); - } - - if (asyncMethod is not null) { - if (!writer.SupportsAsyncMethods) - Error("PDB symbol writer doesn't support writing async methods"); - else - WriteAsyncMethod(ref info, asyncMethod); - } - - writer.CloseMethod(); - } - - void GetPseudoCustomDebugInfos(IList customDebugInfos, List cdiBuilder, out PdbAsyncMethodCustomDebugInfo asyncMethod) { - cdiBuilder.Clear(); - asyncMethod = null; - int count = customDebugInfos.Count; - for (int i = 0; i < count; i++) { - var cdi = customDebugInfos[i]; - switch (cdi.Kind) { - case PdbCustomDebugInfoKind.AsyncMethod: - if (asyncMethod is not 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) - 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; - } - - void WriteAsyncMethod(ref CurrentMethod info, PdbAsyncMethodCustomDebugInfo asyncMethod) { - if (asyncMethod.KickoffMethod is null) { - Error("KickoffMethod is null"); - return; - } - - uint kickoffMethod = GetMethodToken(asyncMethod.KickoffMethod); - writer.DefineKickoffMethod(kickoffMethod); - - if (asyncMethod.CatchHandlerInstruction is not null) { - int catchHandlerILOffset = info.GetOffset(asyncMethod.CatchHandlerInstruction); - writer.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 is null) { - Error("YieldInstruction is null"); - return; - } - if (stepInfo.BreakpointMethod is null) { - Error("BreakpointMethod is null"); - return; - } - if (stepInfo.BreakpointInstruction is 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); - } - writer.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 is 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 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; - } - - 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) { - 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); - writer.DefineConstant(constant.Name, constant.Value ?? boxedZeroInt32, token.Raw); - } - } - 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); - } - static readonly object boxedZeroInt32 = 0; - - void AddLocals(MethodDef method, IList locals, uint startOffset, uint endOffset) { - if (locals.Count == 0) - return; - uint token = metadata.GetLocalVarSigToken(method); - if (token == 0) { - Error("Method {0} ({1:X8}) has no local signature token", method, method.MDToken.Raw); - return; - } - 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 is null) - continue; - writer.DefineLocalVariable(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; - } - - MDToken GetUserEntryPointToken() { - var ep = pdbState.UserEntryPoint; - if (ep is null) - 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 default; - } - 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) => - 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); - - /// - public void Dispose() { - if (writer is not null) - Close(); - writer?.Dispose(); - writer = null; - } - } -} diff --git a/Plugins/dnlib/DotNet/PropertyAttributes.cs b/Plugins/dnlib/DotNet/PropertyAttributes.cs deleted file mode 100644 index 9e08763..0000000 --- a/Plugins/dnlib/DotNet/PropertyAttributes.cs +++ /dev/null @@ -1,18 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Property attributes, see CorHdr.h/CorPropertyAttr - /// - [Flags] - public enum PropertyAttributes : ushort { - /// property is special. Name describes how. - SpecialName = 0x0200, - /// Runtime(metadata internal APIs) should check name encoding. - RTSpecialName = 0x0400, - /// Property has default - HasDefault = 0x1000, - } -} diff --git a/Plugins/dnlib/DotNet/PropertyDef.cs b/Plugins/dnlib/DotNet/PropertyDef.cs deleted file mode 100644 index 67bd1f9..0000000 --- a/Plugins/dnlib/DotNet/PropertyDef.cs +++ /dev/null @@ -1,520 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the Property table - /// - public abstract class PropertyDef : IHasConstant, IHasCustomAttribute, IHasSemantic, IHasCustomDebugInformation, IFullName, IMemberDef { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.Property, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasConstantTag => 2; - - /// - public int HasCustomAttributeTag => 9; - - /// - public int HasSemanticTag => 1; - - /// - /// From column Property.PropFlags - /// - public PropertyAttributes Attributes { - get => (PropertyAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column Property.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column Property.Type - /// - public CallingConventionSig Type { - get => type; - set => type = value; - } - /// - protected CallingConventionSig type; - - /// - public Constant Constant { - get { - if (!constant_isInitialized) - InitializeConstant(); - return constant; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - constant = value; - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected Constant constant; - /// - protected bool constant_isInitialized; - - void InitializeConstant() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (constant_isInitialized) - return; - constant = GetConstant_NoLock(); - constant_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual Constant GetConstant_NoLock() => null; - - /// Reset - protected void ResetConstant() => constant_isInitialized = false; - - /// - /// 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 int HasCustomDebugInformationTag => 9; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Gets/sets the first getter method. Writing null will clear all get methods. - /// - public MethodDef GetMethod { - get { - if (otherMethods is null) - InitializePropertyMethods(); - return getMethods.Count == 0 ? null : getMethods[0]; - } - set { - if (otherMethods is null) - InitializePropertyMethods(); - if (value is null) - getMethods.Clear(); - else if (getMethods.Count == 0) - getMethods.Add(value); - else - getMethods[0] = value; - } - } - - /// - /// Gets/sets the first setter method. Writing null will clear all set methods. - /// - public MethodDef SetMethod { - get { - if (otherMethods is null) - InitializePropertyMethods(); - return setMethods.Count == 0 ? null : setMethods[0]; - } - set { - if (otherMethods is null) - InitializePropertyMethods(); - if (value is null) - setMethods.Clear(); - else if (setMethods.Count == 0) - setMethods.Add(value); - else - setMethods[0] = value; - } - } - - /// - /// Gets all getter methods - /// - public IList GetMethods { - get { - if (otherMethods is null) - InitializePropertyMethods(); - return getMethods; - } - } - - /// - /// Gets all setter methods - /// - public IList SetMethods { - get { - if (otherMethods is null) - InitializePropertyMethods(); - return setMethods; - } - } - - /// - /// Gets the other methods - /// - public IList OtherMethods { - get { - if (otherMethods is null) - InitializePropertyMethods(); - return otherMethods; - } - } - - void InitializePropertyMethods() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (otherMethods is null) - InitializePropertyMethods_NoLock(); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - /// Initializes , , - /// and . - /// - protected virtual void InitializePropertyMethods_NoLock() { - getMethods = new List(); - setMethods = new List(); - otherMethods = new List(); - } - - /// - protected IList getMethods; - /// - protected IList setMethods; - /// - protected IList otherMethods; - - /// Reset , , - protected void ResetMethods() => otherMethods = null; - - /// - /// true if there are no methods attached to this property - /// - 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 => CustomAttributes.Count > 0; - - /// - /// true if is not empty - /// - public bool HasOtherMethods => OtherMethods.Count > 0; - - /// - /// true if is not null - /// - public bool HasConstant => Constant is not null; - - /// - /// Gets the constant element type or if there's no constant - /// - public ElementType ElementType { - get { - var c = Constant; - return c is null ? ElementType.End : c.Type; - } - } - - /// - /// Gets/sets the property sig - /// - public PropertySig PropertySig { - get => type as PropertySig; - set => type = value; - } - - /// - /// Gets/sets the declaring type (owner type) - /// - public TypeDef DeclaringType { - get => declaringType2; - set { - var currentDeclaringType = DeclaringType2; - if (currentDeclaringType == value) - return; - if (currentDeclaringType is not null) - currentDeclaringType.Properties.Remove(this); // Will set DeclaringType2 = null - if (value is not null) - value.Properties.Add(this); // Will set DeclaringType2 = value - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType => declaringType2; - - /// - /// Called by and should normally not be called by any user - /// code. Use instead. Only call this if you must set the - /// declaring type without inserting it in the declaring type's method list. - /// - public TypeDef DeclaringType2 { - get => declaringType2; - set => declaringType2 = value; - } - /// - protected TypeDef declaringType2; - - /// - public ModuleDef Module => declaringType2?.Module; - - /// - /// Gets the full name of the property - /// - public string FullName => FullNameFactory.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 - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, PropertyAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((PropertyAttributes)attributes & PropertyAttributes.SpecialName) != 0; - set => ModifyAttributes(value, PropertyAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((PropertyAttributes)attributes & PropertyAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, PropertyAttributes.RTSpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool HasDefault { - get => ((PropertyAttributes)attributes & PropertyAttributes.HasDefault) != 0; - set => ModifyAttributes(value, PropertyAttributes.HasDefault); - } - - /// - public override string ToString() => FullName; - } - - /// - /// A Property row created by the user and not present in the original .NET file - /// - public class PropertyDefUser : PropertyDef { - /// - /// Default constructor - /// - public PropertyDefUser() { - } - - /// - /// Constructor - /// - /// Name - public PropertyDefUser(UTF8String name) - : this(name, null) { - } - - /// - /// Constructor - /// - /// Name - /// Property signature - public PropertyDefUser(UTF8String name, PropertySig sig) - : this(name, sig, 0) { - } - - /// - /// Constructor - /// - /// Name - /// Property signature - /// Flags - public PropertyDefUser(UTF8String name, PropertySig sig, PropertyAttributes flags) { - this.name = name; - type = sig; - attributes = (int)flags; - } - } - - /// - /// Created from a row in the Property table - /// - sealed class PropertyDefMD : PropertyDef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - - /// - public uint OrigRid => origRid; - - /// - protected override Constant GetConstant_NoLock() => readerModule.ResolveConstant(readerModule.Metadata.GetConstantRid(Table.Property, origRid)); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.Property, 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(declaringType2), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this Property row - /// Row ID - /// If is null - /// If is invalid - public PropertyDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.PropertyTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"Property rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadPropertyRow(origRid, out var row); - Debug.Assert(b); - attributes = row.PropFlags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - declaringType2 = readerModule.GetOwnerType(this); - type = readerModule.ReadSignature(row.Type, new GenericParamContext(declaringType2)); - } - - internal PropertyDefMD InitializeAll() { - MemberMDInitializer.Initialize(Attributes); - MemberMDInitializer.Initialize(Name); - MemberMDInitializer.Initialize(Type); - MemberMDInitializer.Initialize(Constant); - MemberMDInitializer.Initialize(CustomAttributes); - MemberMDInitializer.Initialize(GetMethod); - MemberMDInitializer.Initialize(SetMethod); - MemberMDInitializer.Initialize(OtherMethods); - MemberMDInitializer.Initialize(DeclaringType); - return this; - } - - /// - protected override void InitializePropertyMethods_NoLock() { - if (otherMethods is not null) - return; - IList newOtherMethods; - IList newGetMethods, newSetMethods; - var dt = declaringType2 as TypeDefMD; - if (dt is null) { - newGetMethods = new List(); - newSetMethods = new List(); - newOtherMethods = new List(); - } - else - dt.InitializeProperty(this, out newGetMethods, out newSetMethods, out newOtherMethods); - getMethods = newGetMethods; - setMethods = newSetMethods; - // Must be initialized last - otherMethods = newOtherMethods; - } - } -} diff --git a/Plugins/dnlib/DotNet/PublicKey.cs b/Plugins/dnlib/DotNet/PublicKey.cs deleted file mode 100644 index 14b75d9..0000000 --- a/Plugins/dnlib/DotNet/PublicKey.cs +++ /dev/null @@ -1,62 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Threading; - -namespace dnlib.DotNet { - /// - /// Represents a public key - /// - public sealed class PublicKey : PublicKeyBase { - const AssemblyHashAlgorithm DEFAULT_ALGORITHM = AssemblyHashAlgorithm.SHA1; - PublicKeyToken publicKeyToken; - - /// - /// Gets the - /// - public override PublicKeyToken Token { - get { - if (publicKeyToken is null && !IsNullOrEmpty) - Interlocked.CompareExchange(ref publicKeyToken, AssemblyHash.CreatePublicKeyToken(data), null); - return publicKeyToken; - } - } - - /// - public override byte[] Data => data; - - /// - /// Constructor - /// - public PublicKey() : base((byte[])null) { } - - /// - /// Constructor - /// - /// Public key data - public PublicKey(byte[] data) - : base(data) { - } - - /// - /// Constructor - /// - /// Public key data as a hex string or the string "null" - /// to set public key data to null - public PublicKey(string hexString) - : base(hexString) { - } - - /// - public override bool Equals(object obj) { - if ((object)this == obj) - return true; - var other = obj as PublicKey; - if (other is null) - return false; - return Utils.Equals(Data, other.Data); - } - - /// - public override int GetHashCode() => Utils.GetHashCode(Data); - } -} diff --git a/Plugins/dnlib/DotNet/PublicKeyBase.cs b/Plugins/dnlib/DotNet/PublicKeyBase.cs deleted file mode 100644 index 2010174..0000000 --- a/Plugins/dnlib/DotNet/PublicKeyBase.cs +++ /dev/null @@ -1,176 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Public key / public key token base class - /// - public abstract class PublicKeyBase { - /// - /// The key data - /// - protected readonly byte[] data; - - /// - /// Returns true if is null or empty - /// - public bool IsNullOrEmpty => data is null || data.Length == 0; - - /// - /// Returns true if is null - /// - public bool IsNull => Data is null; - - /// - /// Gets/sets key data - /// - public virtual byte[] Data => data; - - /// - /// Gets the - /// - public abstract PublicKeyToken Token { get; } - - /// - /// Constructor - /// - /// Key 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) => data = Parse(hexString); - - static byte[] Parse(string hexString) { - if (hexString is null || hexString == "null") - return null; - return Utils.ParseBytes(hexString); - } - - /// - /// Checks whether a public key or token is null or empty - /// - /// Public key or token instance - public static bool IsNullOrEmpty2(PublicKeyBase a) => a is null || a.IsNullOrEmpty; - - /// - /// Returns a - /// - /// A or a instance - public static PublicKeyToken ToPublicKeyToken(PublicKeyBase pkb) { - if (pkb is PublicKeyToken pkt) - return pkt; - if (pkb is PublicKey pk) - return pk.Token; - return null; - } - - /// - /// Compares two s as s - /// - /// First - /// Second - /// < 0 if a < b, 0 if a == b, > 0 if a > b - public static int TokenCompareTo(PublicKeyBase a, PublicKeyBase b) { - if (a == b) - return 0; - return TokenCompareTo(ToPublicKeyToken(a), ToPublicKeyToken(b)); - } - - /// - /// Checks whether two public key tokens are equal - /// - /// First - /// Second - /// true if same, false otherwise - public static bool TokenEquals(PublicKeyBase a, PublicKeyBase b) => TokenCompareTo(a, b) == 0; - - static readonly byte[] EmptyByteArray = Array2.Empty(); - /// - /// Compares two s - /// - /// First - /// Second - /// < 0 if a < b, 0 if a == b, > 0 if a > b - public static int TokenCompareTo(PublicKeyToken a, PublicKeyToken b) { - if (a == b) - return 0; - return TokenCompareTo(a?.Data, b?.Data); - } - - static int TokenCompareTo(byte[] a, byte[] b) => Utils.CompareTo(a ?? EmptyByteArray, b ?? EmptyByteArray); - - /// - /// Checks whether two public key tokens are equal - /// - /// First - /// Second - /// true if same, false otherwise - 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) => GetHashCode(ToPublicKeyToken(a)); - - /// - /// Gets the public key token hash code - /// - /// Public key token - /// The hash code - public static int GetHashCode(PublicKeyToken a) { - if (a is null) - return 0; - return Utils.GetHashCode(a.Data); - } - - /// - /// Creates a - /// - /// Public key data or null - /// A new instance or null if - /// was null - public static PublicKey CreatePublicKey(byte[] data) { - if (data is null) - return null; - return new PublicKey(data); - } - - /// - /// Creates a - /// - /// Public key token data or null - /// A new instance or null if - /// was null - public static PublicKeyToken CreatePublicKeyToken(byte[] data) { - if (data is null) - return null; - return new PublicKeyToken(data); - } - - /// - /// Gets the raw public key / public key token byte array - /// - /// The instance or null - /// Raw public key / public key token data or null - public static byte[] GetRawData(PublicKeyBase pkb) { - if (pkb is null) - return null; - return pkb.Data; - } - - /// - public override string ToString() { - var d = Data; - if (d is null || d.Length == 0) - return "null"; - return Utils.ToHex(d, false); - } - } -} diff --git a/Plugins/dnlib/DotNet/PublicKeyToken.cs b/Plugins/dnlib/DotNet/PublicKeyToken.cs deleted file mode 100644 index b6fc505..0000000 --- a/Plugins/dnlib/DotNet/PublicKeyToken.cs +++ /dev/null @@ -1,41 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Represents a public key token - /// - public sealed class PublicKeyToken : PublicKeyBase { - /// - /// Gets the - /// - public override PublicKeyToken Token => this; - - /// - /// Constructor - /// - public PublicKeyToken() : base((byte[])null) { } - - /// - public PublicKeyToken(byte[] data) - : base(data) { - } - - /// - public PublicKeyToken(string hexString) - : base(hexString) { - } - - /// - public override bool Equals(object obj) { - if ((object)this == obj) - return true; - var other = obj as PublicKeyToken; - if (other is null) - return false; - return Utils.Equals(Data, other.Data); - } - - /// - public override int GetHashCode() => Utils.GetHashCode(Data); - } -} diff --git a/Plugins/dnlib/DotNet/RecursionCounter.cs b/Plugins/dnlib/DotNet/RecursionCounter.cs deleted file mode 100644 index a5ddff1..0000000 --- a/Plugins/dnlib/DotNet/RecursionCounter.cs +++ /dev/null @@ -1,50 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// Recursion counter - /// - struct RecursionCounter { - /// - /// Max recursion count. If this is reached, we won't continue, and will use a default value. - /// - public const int MAX_RECURSION_COUNT = 100; - int counter; - - /// - /// Gets the recursion counter - /// - public int Counter => counter; - - /// - /// Increments if it's not too high. ALL instance methods - /// that can be called recursively must call this method and - /// (if this method returns true) - /// - /// true if it was incremented and caller can continue, false if - /// it was not incremented and the caller must return to its caller. - public bool Increment() { - if (counter >= MAX_RECURSION_COUNT) - return false; - counter++; - return true; - } - - /// - /// Must be called before returning to caller if - /// returned true. - /// - public void Decrement() { -#if DEBUG - if (counter <= 0) - throw new InvalidOperationException("recursionCounter <= 0"); -#endif - counter--; - } - - /// - public override string ToString() => counter.ToString(); - } -} diff --git a/Plugins/dnlib/DotNet/ReflectionExtensions.cs b/Plugins/dnlib/DotNet/ReflectionExtensions.cs deleted file mode 100644 index 5e29bac..0000000 --- a/Plugins/dnlib/DotNet/ReflectionExtensions.cs +++ /dev/null @@ -1,146 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Reflection; -using System.Text; - -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 = Unescape(type.Name) ?? string.Empty; - if (!type.IsNested) - @namespace = type.Namespace ?? string.Empty; - else { - var declTypeFullName = Unescape(type.DeclaringType.FullName); - var typeFullName = Unescape(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 - /// - /// The type - 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 not null) - return (bool)prop.GetValue(self, Array2.Empty()); - return (self.Name ?? string.Empty).EndsWith("[]"); - } - - /// - /// Gets a 's - /// - /// The type - /// The type's element type - public static ElementType GetElementType2(this Type a) { - if (a is null) - return ElementType.End; // Any invalid one is good enough - if (a.IsArray) - return IsSZArray(a) ? ElementType.SZArray : ElementType.Array; - if (a.IsByRef) - return ElementType.ByRef; - if (a.IsPointer) - return ElementType.Ptr; - if (a.IsGenericParameter) - return a.DeclaringMethod is null ? ElementType.Var : ElementType.MVar; - if (a.IsGenericType && !a.IsGenericTypeDefinition) - return ElementType.GenericInst; - - if (a == typeof(void)) return ElementType.Void; - if (a == typeof(bool)) return ElementType.Boolean; - if (a == typeof(char)) return ElementType.Char; - if (a == typeof(sbyte)) return ElementType.I1; - if (a == typeof(byte)) return ElementType.U1; - if (a == typeof(short)) return ElementType.I2; - if (a == typeof(ushort)) return ElementType.U2; - if (a == typeof(int)) return ElementType.I4; - if (a == typeof(uint)) return ElementType.U4; - if (a == typeof(long)) return ElementType.I8; - if (a == typeof(ulong)) return ElementType.U8; - if (a == typeof(float)) return ElementType.R4; - if (a == typeof(double)) return ElementType.R8; - if (a == typeof(string)) return ElementType.String; - if (a == typeof(TypedReference))return ElementType.TypedByRef; - if (a == typeof(IntPtr)) return ElementType.I; - if (a == typeof(UIntPtr)) return ElementType.U; - if (a == typeof(object)) return ElementType.Object; - - 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. - /// - /// The method - public static bool IsGenericButNotGenericMethodDefinition(this MethodBase mb) => - mb is not null && !mb.IsGenericMethodDefinition && mb.IsGenericMethod; - - /// - /// Checks whether a parameter/prop/event type should be treated as if it is really a - /// generic instance type and not a generic type definition. In the .NET metadata (method - /// sig), the parameter is a generic instance type, but the CLR treats it as if it's just - /// 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 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; - - /// - /// 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) => - type is not 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/Plugins/dnlib/DotNet/ResolveException.cs b/Plugins/dnlib/DotNet/ResolveException.cs deleted file mode 100644 index dc6f294..0000000 --- a/Plugins/dnlib/DotNet/ResolveException.cs +++ /dev/null @@ -1,158 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.Serialization; - -namespace dnlib.DotNet { - /// - /// Resolve exception base class - /// - [Serializable] - public class ResolveException : Exception { - /// - /// Default constructor - /// - public ResolveException() { - } - - /// - /// Constructor - /// - /// Exception message - public ResolveException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Exception message - /// Inner exception or null if none - public ResolveException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected ResolveException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Thrown if an assembly couldn't be resolved - /// - [Serializable] - public class AssemblyResolveException : ResolveException { - /// - /// Default constructor - /// - public AssemblyResolveException() { - } - - /// - /// Constructor - /// - /// Exception message - public AssemblyResolveException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Exception message - /// Inner exception or null if none - public AssemblyResolveException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected AssemblyResolveException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Thrown if a type couldn't be resolved - /// - [Serializable] - public class TypeResolveException : ResolveException { - /// - /// Default constructor - /// - public TypeResolveException() { - } - - /// - /// Constructor - /// - /// Exception message - public TypeResolveException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Exception message - /// Inner exception or null if none - public TypeResolveException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected TypeResolveException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Thrown if a method/field couldn't be resolved - /// - [Serializable] - public class MemberRefResolveException : ResolveException { - /// - /// Default constructor - /// - public MemberRefResolveException() { - } - - /// - /// Constructor - /// - /// Exception message - public MemberRefResolveException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Exception message - /// Inner exception or null if none - public MemberRefResolveException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected MemberRefResolveException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } -} diff --git a/Plugins/dnlib/DotNet/Resolver.cs b/Plugins/dnlib/DotNet/Resolver.cs deleted file mode 100644 index 067ff06..0000000 --- a/Plugins/dnlib/DotNet/Resolver.cs +++ /dev/null @@ -1,163 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Resolves types, methods, fields - /// - public sealed class Resolver : IResolver { - readonly IAssemblyResolver assemblyResolver; - - /// - /// true to project WinMD types to CLR types, eg. Windows.UI.Xaml.Interop.TypeName - /// gets converted to System.Type before trying to resolve the type. This is enabled - /// by default. - /// - public bool ProjectWinMDRefs { - get => projectWinMDRefs; - set => projectWinMDRefs = value; - } - bool projectWinMDRefs = true; - - /// - /// Constructor - /// - /// The assembly resolver - public Resolver(IAssemblyResolver assemblyResolver) => - this.assemblyResolver = assemblyResolver ?? throw new ArgumentNullException(nameof(assemblyResolver)); - - /// - public TypeDef Resolve(TypeRef typeRef, ModuleDef sourceModule) { - if (typeRef is null) - return null; - - if (ProjectWinMDRefs) - typeRef = WinMDHelpers.ToCLR(typeRef.Module ?? sourceModule, typeRef) ?? typeRef; - - var nonNestedTypeRef = TypeRef.GetNonNestedTypeRef(typeRef); - 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 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 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 is null) - return null; - var resolvedModule = nonNestedAssembly.FindModule(moduleRef.Name); - return resolvedModule is null ? null : resolvedModule.Find(typeRef) ?? - 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; - } - - TypeDef ResolveExportedType(IList modules, TypeRef typeRef, ModuleDef sourceModule) { - for (int i = 0; i < 30; i++) { - var exportedType = FindExportedType(modules, typeRef); - if (exportedType is null) - return null; - - var asmResolver = modules[0].Context.AssemblyResolver; - var etAsm = asmResolver.Resolve(exportedType.DefinitionAssembly, sourceModule ?? typeRef.Module); - if (etAsm is null) - return null; - - var td = etAsm.Find(typeRef); - if (td is not null) - return td; - - modules = etAsm.Modules; - } - - return null; - } - - static ExportedType FindExportedType(IList modules, TypeRef typeRef) { - if (typeRef is null) - return null; - 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; - } - } - return null; - } - - /// - public IMemberForwarded Resolve(MemberRef memberRef) { - if (memberRef is null) - return null; - if (ProjectWinMDRefs) - memberRef = WinMDHelpers.ToCLR(memberRef.Module, memberRef) ?? memberRef; - var parent = memberRef.Class; - if (parent is MethodDef method) - return method; - return GetDeclaringType(memberRef, parent)?.Resolve(memberRef); - } - - TypeDef GetDeclaringType(MemberRef memberRef, IMemberRefParent parent) { - if (memberRef is null || parent is null) - return null; - - if (parent is TypeSpec ts) - parent = ts.ScopeType; - - if (parent is TypeDef declaringTypeDef) - return declaringTypeDef; - - 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. - if (parent is ModuleRef moduleRef) { - var module = memberRef.Module; - if (module is null) - return null; - TypeDef globalType = null; - if (new SigComparer().Equals(module, moduleRef)) - globalType = module.GlobalType; - var modAsm = module.Assembly; - if (globalType is null && modAsm is not null) { - var moduleDef = modAsm.FindModule(moduleRef.Name); - if (moduleDef is not null) - globalType = moduleDef.GlobalType; - } - return globalType; - } - - if (parent is MethodDef method) - return method.DeclaringType; - - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Resource.cs b/Plugins/dnlib/DotNet/Resource.cs deleted file mode 100644 index 58bb2e1..0000000 --- a/Plugins/dnlib/DotNet/Resource.cs +++ /dev/null @@ -1,369 +0,0 @@ -// 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 { - /// - /// Type of resource - /// - public enum ResourceType { - /// - /// It's a - /// - Embedded, - - /// - /// It's a - /// - AssemblyLinked, - - /// - /// It's a - /// - Linked, - } - - /// - /// Resource base class - /// - public abstract class Resource : IMDTokenProvider, IHasCustomAttribute, IHasCustomDebugInformation { - private protected uint rid; - private protected uint? offset; - UTF8String name; - ManifestResourceAttributes flags; - - /// - public MDToken MDToken => new MDToken(Table.ManifestResource, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - /// Gets/sets the offset of the resource - /// - public uint? Offset { - get => offset; - set => offset = value; - } - - /// - /// Gets/sets the name - /// - public UTF8String Name { - get => name; - set => name = value; - } - - /// - /// Gets/sets the flags - /// - public ManifestResourceAttributes Attributes { - get => flags; - set => flags = value; - } - - /// - /// Gets the type of resource - /// - public abstract ResourceType ResourceType { get; } - - /// - /// Gets/sets the visibility - /// - public ManifestResourceAttributes Visibility { - get => flags & ManifestResourceAttributes.VisibilityMask; - set => flags = (flags & ~ManifestResourceAttributes.VisibilityMask) | (value & ManifestResourceAttributes.VisibilityMask); - } - - /// - /// true if is set - /// - public bool IsPublic => (flags & ManifestResourceAttributes.VisibilityMask) == ManifestResourceAttributes.Public; - - /// - /// true if is set - /// - 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 - /// - /// Name - /// flags - protected Resource(UTF8String name, ManifestResourceAttributes flags) { - this.name = name; - this.flags = flags; - } - } - - /// - /// A resource that is embedded in a .NET module. This is the most common type of resource. - /// - public class EmbeddedResource : Resource { - readonly DataReaderFactory dataReaderFactory; - readonly uint resourceStartOffset; - readonly uint resourceLength; - - /// - /// Gets the length of the data - /// - public uint Length => resourceLength; - - /// - public override ResourceType ResourceType => ResourceType.Embedded; - - /// - /// Constructor - /// - /// Name of resource - /// Resource data - /// Resource flags - public EmbeddedResource(UTF8String name, byte[] data, ManifestResourceAttributes flags = ManifestResourceAttributes.Private) - : this(name, ByteArrayDataReaderFactory.Create(data, filename: null), 0, (uint)data.Length, flags) { - } - - /// - /// Constructor - /// - /// Name of resource - /// Data reader factory - /// Offset of resource data - /// Length of resource data - /// Resource flags - public EmbeddedResource(UTF8String name, DataReaderFactory dataReaderFactory, uint offset, uint length, ManifestResourceAttributes flags = ManifestResourceAttributes.Private) - : base(name, flags) { - this.dataReaderFactory = dataReaderFactory ?? throw new ArgumentNullException(nameof(dataReaderFactory)); - resourceStartOffset = offset; - resourceLength = length; - } - - /// - /// Gets a data reader that can access the resource - /// - /// - public DataReader CreateReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); - - /// - 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 class AssemblyLinkedResource : Resource { - AssemblyRef asmRef; - - /// - public override ResourceType ResourceType => ResourceType.AssemblyLinked; - - /// - /// Gets/sets the assembly reference - /// - public AssemblyRef Assembly { - get => asmRef; - set => asmRef = value ?? throw new ArgumentNullException(nameof(value)); - } - - /// - /// Constructor - /// - /// Name of resource - /// Assembly reference - /// Resource flags - public AssemblyLinkedResource(UTF8String name, AssemblyRef asmRef, ManifestResourceAttributes flags) - : base(name, flags) => this.asmRef = asmRef ?? throw new ArgumentNullException(nameof(asmRef)); - - /// - 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 class LinkedResource : Resource { - FileDef file; - - /// - public override ResourceType ResourceType => ResourceType.Linked; - - /// - /// Gets/sets the file - /// - public FileDef File { - get => file; - set => file = value ?? throw new ArgumentNullException(nameof(value)); - } - - /// - /// Gets/sets the hash - /// - public byte[] Hash { - get => file.HashValue; - set => file.HashValue = value; - } - - /// - /// Gets/sets the file name - /// - public UTF8String FileName => file is null ? UTF8String.Empty : file.Name; - - /// - /// Constructor - /// - /// Name of resource - /// The file - /// Resource flags - public LinkedResource(UTF8String name, FileDef file, ManifestResourceAttributes flags) - : base(name, flags) => this.file = file; - - /// - 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; - } - } -} diff --git a/Plugins/dnlib/DotNet/ResourceCollection.cs b/Plugins/dnlib/DotNet/ResourceCollection.cs deleted file mode 100644 index debc42b..0000000 --- a/Plugins/dnlib/DotNet/ResourceCollection.cs +++ /dev/null @@ -1,159 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.Utils; -using System; - -namespace dnlib.DotNet { - /// - /// A collection of s - /// - public class ResourceCollection : LazyList { - /// - /// Default constructor - /// - public ResourceCollection() { - } - - /// - /// Constructor - /// - /// List listener - public ResourceCollection(IListListener listener) - : base(listener) { - } - - /// - /// Constructor - /// - /// Initial length of the list - /// Context passed to - /// Delegate instance that returns original values - public ResourceCollection(int length, object context, Func readOriginalValue) - : base(length, context, readOriginalValue) { - } - - /// - /// Finds the index of a resource - /// - /// Name of resource - /// The index of the or -1 if none was found - public int IndexOf(UTF8String name) { - int i = -1; - foreach (var resource in this) { - i++; - if (resource is not null && resource.Name == name) - return i; - } - return -1; - } - - /// - /// Finds the index of an embedded resource - /// - /// Name of resource - /// The index of the or -1 if none was found - public int IndexOfEmbeddedResource(UTF8String name) { - int i = -1; - foreach (var resource in this) { - i++; - if (resource is not null && - resource.ResourceType == ResourceType.Embedded && - resource.Name == name) - return i; - } - return -1; - } - - /// - /// Finds the index of an assembly linked resource - /// - /// Name of resource - /// The index of the or -1 if none was found - public int IndexOfAssemblyLinkedResource(UTF8String name) { - int i = -1; - foreach (var resource in this) { - i++; - if (resource is not null && - resource.ResourceType == ResourceType.AssemblyLinked && - resource.Name == name) - return i; - } - return -1; - } - - /// - /// Finds the index of a linked resource - /// - /// Name of resource - /// The index of the or -1 if none was found - public int IndexOfLinkedResource(UTF8String name) { - int i = -1; - foreach (var resource in this) { - i++; - if (resource is not null && - resource.ResourceType == ResourceType.Linked && - resource.Name == name) - return i; - } - return -1; - } - - /// - /// Finds a resource - /// - /// Name of resource - /// The or null if none was found - public Resource Find(UTF8String name) { - foreach (var resource in this) { - if (resource is not null && resource.Name == name) - return resource; - } - return null; - } - - /// - /// Finds an embedded resource - /// - /// Name of resource - /// The or null if none was found - public EmbeddedResource FindEmbeddedResource(UTF8String name) { - foreach (var resource in this) { - if (resource is not null && - resource.ResourceType == ResourceType.Embedded && - resource.Name == name) - return (EmbeddedResource)resource; - } - return null; - } - - /// - /// Finds an assembly linked resource - /// - /// Name of resource - /// The or null if none was found - public AssemblyLinkedResource FindAssemblyLinkedResource(UTF8String name) { - foreach (var resource in this) { - if (resource is not null && - resource.ResourceType == ResourceType.AssemblyLinked && - resource.Name == name) - return (AssemblyLinkedResource)resource; - } - return null; - } - - /// - /// Finds a linked resource - /// - /// Name of resource - /// The or null if none was found - public LinkedResource FindLinkedResource(UTF8String name) { - foreach (var resource in this) { - if (resource is not null && - resource.ResourceType == ResourceType.Linked && - resource.Name == name) - return (LinkedResource)resource; - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Resources/BuiltInResourceData.cs b/Plugins/dnlib/DotNet/Resources/BuiltInResourceData.cs deleted file mode 100644 index 8bb1c82..0000000 --- a/Plugins/dnlib/DotNet/Resources/BuiltInResourceData.cs +++ /dev/null @@ -1,164 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.Serialization; -using dnlib.IO; - -namespace dnlib.DotNet.Resources { - /// - /// Built-in resource data - /// - public sealed class BuiltInResourceData : IResourceData { - readonly ResourceTypeCode code; - readonly object data; - - /// - /// Gets the data - /// - public object Data => data; - - /// - public ResourceTypeCode Code => code; - - /// - public FileOffset StartOffset { get; set; } - - /// - public FileOffset EndOffset { get; set; } - - /// - /// Constructor - /// - /// Type of data - /// Data - public BuiltInResourceData(ResourceTypeCode code, object data) { - this.code = code; - this.data = data; - } - - /// - public void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { - switch (code) { - case ResourceTypeCode.Null: - break; - - case ResourceTypeCode.String: - writer.Write((string)data); - break; - - case ResourceTypeCode.Boolean: - writer.Write((bool)data); - break; - - case ResourceTypeCode.Char: - writer.Write((ushort)(char)data); - break; - - case ResourceTypeCode.Byte: - writer.Write((byte)data); - break; - - case ResourceTypeCode.SByte: - writer.Write((sbyte)data); - break; - - case ResourceTypeCode.Int16: - writer.Write((short)data); - break; - - case ResourceTypeCode.UInt16: - writer.Write((ushort)data); - break; - - case ResourceTypeCode.Int32: - writer.Write((int)data); - break; - - case ResourceTypeCode.UInt32: - writer.Write((uint)data); - break; - - case ResourceTypeCode.Int64: - writer.Write((long)data); - break; - - case ResourceTypeCode.UInt64: - writer.Write((ulong)data); - break; - - case ResourceTypeCode.Single: - writer.Write((float)data); - break; - - case ResourceTypeCode.Double: - writer.Write((double)data); - break; - - case ResourceTypeCode.Decimal: - writer.Write((decimal)data); - break; - - case ResourceTypeCode.DateTime: - var dateTime = (DateTime)data; - if (writer.FormatVersion == 1) - writer.Write(dateTime.Ticks); - else - writer.Write(dateTime.ToBinary()); - break; - - case ResourceTypeCode.TimeSpan: - writer.Write(((TimeSpan)data).Ticks); - break; - - case ResourceTypeCode.ByteArray: - case ResourceTypeCode.Stream: - if (writer.FormatVersion == 1) - throw new NotSupportedException($"{code} is not supported in format version 1 resources"); - var ary = (byte[])data; - writer.Write(ary.Length); - writer.Write(ary); - break; - - default: - throw new InvalidOperationException("Unknown resource type code"); - } - } - - /// - public override string ToString() { - switch (code) { - case ResourceTypeCode.Null: - return "null"; - - case ResourceTypeCode.String: - case ResourceTypeCode.Boolean: - case ResourceTypeCode.Char: - case ResourceTypeCode.Byte: - case ResourceTypeCode.SByte: - case ResourceTypeCode.Int16: - case ResourceTypeCode.UInt16: - case ResourceTypeCode.Int32: - case ResourceTypeCode.UInt32: - case ResourceTypeCode.Int64: - case ResourceTypeCode.UInt64: - case ResourceTypeCode.Single: - case ResourceTypeCode.Double: - case ResourceTypeCode.Decimal: - case ResourceTypeCode.DateTime: - case ResourceTypeCode.TimeSpan: - return $"{code}: '{data}'"; - - case ResourceTypeCode.ByteArray: - case ResourceTypeCode.Stream: - var ary = data as byte[]; - if (ary is not null) - return $"{code}: Length: {ary.Length}"; - return $"{code}: '{data}'"; - - default: - return $"{code}: '{data}'"; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Resources/IResourceData.cs b/Plugins/dnlib/DotNet/Resources/IResourceData.cs deleted file mode 100644 index 8ec368b..0000000 --- a/Plugins/dnlib/DotNet/Resources/IResourceData.cs +++ /dev/null @@ -1,35 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.IO; -using System.Runtime.Serialization; -using dnlib.IO; - -namespace dnlib.DotNet.Resources { - /// - /// Implemented by all resource data - /// - public interface IResourceData : IFileSection { - /// - /// Gets the type of data - /// - ResourceTypeCode Code { get; } - - /// - /// Start offset of the section in the file - /// - new FileOffset StartOffset { get; set; } - - /// - /// End offset of the section in the file. This is one byte after the last - /// valid offset in the section. - /// - new FileOffset EndOffset { get; set; } - - /// - /// Writes the data - /// - /// Writer - /// Formatter if needed by implementer - void WriteData(ResourceBinaryWriter writer, IFormatter formatter); - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceBinaryWriter.cs b/Plugins/dnlib/DotNet/Resources/ResourceBinaryWriter.cs deleted file mode 100644 index 09d7aef..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceBinaryWriter.cs +++ /dev/null @@ -1,26 +0,0 @@ -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; } - - internal 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/Plugins/dnlib/DotNet/Resources/ResourceDataFactory.cs b/Plugins/dnlib/DotNet/Resources/ResourceDataFactory.cs deleted file mode 100644 index ef43770..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceDataFactory.cs +++ /dev/null @@ -1,339 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; - -namespace dnlib.DotNet.Resources { - /// - /// Creates resource data - /// - public class ResourceDataFactory { - readonly ModuleDef module; - readonly ModuleDefMD moduleMD; - readonly Dictionary dict = new Dictionary(StringComparer.Ordinal); - readonly Dictionary asmNameToAsmFullName = new Dictionary(StringComparer.Ordinal); - - /// - /// Gets the owner module - /// - protected ModuleDef Module => module; - - /// - /// Constructor - /// - /// Owner module - public ResourceDataFactory(ModuleDef module) { - this.module = module; - moduleMD = module as ModuleDefMD; - } - - /// - /// Gets number of user data types - /// - public int Count => dict.Count; - - /// - /// Create null data - /// - /// - public BuiltInResourceData CreateNull() => new BuiltInResourceData(ResourceTypeCode.Null, null); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(string value) => new BuiltInResourceData(ResourceTypeCode.String, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(bool value) => new BuiltInResourceData(ResourceTypeCode.Boolean, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(char value) => new BuiltInResourceData(ResourceTypeCode.Char, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(byte value) => new BuiltInResourceData(ResourceTypeCode.Byte, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(sbyte value) => new BuiltInResourceData(ResourceTypeCode.SByte, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(short value) => new BuiltInResourceData(ResourceTypeCode.Int16, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(ushort value) => new BuiltInResourceData(ResourceTypeCode.UInt16, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(int value) => new BuiltInResourceData(ResourceTypeCode.Int32, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(uint value) => new BuiltInResourceData(ResourceTypeCode.UInt32, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(long value) => new BuiltInResourceData(ResourceTypeCode.Int64, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(ulong value) => new BuiltInResourceData(ResourceTypeCode.UInt64, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(float value) => new BuiltInResourceData(ResourceTypeCode.Single, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(double value) => new BuiltInResourceData(ResourceTypeCode.Double, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(decimal value) => new BuiltInResourceData(ResourceTypeCode.Decimal, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(DateTime value) => new BuiltInResourceData(ResourceTypeCode.DateTime, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData Create(TimeSpan value) => new BuiltInResourceData(ResourceTypeCode.TimeSpan, value); - - /// - /// Creates array data - /// - /// Value - /// - public BuiltInResourceData Create(byte[] value) => new BuiltInResourceData(ResourceTypeCode.ByteArray, value); - - /// - /// Creates data - /// - /// Value - /// - public BuiltInResourceData CreateStream(byte[] value) => new BuiltInResourceData(ResourceTypeCode.Stream, value); - - /// - /// 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); - - /// - /// Creates serialized data - /// - /// Serialized data - /// - 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, SerializationFormat.BinaryFormatter); - } - - sealed class MyBinder : SerializationBinder { - public class OkException : Exception { - public string AssemblyName { get; set; } - public string TypeName { get; set; } - } - - 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) { - 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; - typeName = ex.TypeName; - return true; - } - catch { - } - - assemblyName = null; - typeName = null; - 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. - /// - /// Full name of type - /// - public UserResourceType CreateUserResourceType(string fullName) => CreateUserResourceType(fullName, false); - - /// - /// Creates a user type. If the type already exists, the existing value is returned. - /// - /// Full name of type - /// Use without converting it to a - /// type in an existing assembly reference - /// - UserResourceType CreateUserResourceType(string fullName, bool useFullName) { - if (dict.TryGetValue(fullName, out var type)) - return type; - - var newFullName = useFullName ? fullName : GetRealTypeFullName(fullName); - type = new UserResourceType(newFullName, ResourceTypeCode.UserTypes + dict.Count); - dict[fullName] = type; - dict[newFullName] = type; - return type; - } - - string GetRealTypeFullName(string fullName) { - var tr = TypeNameParser.ParseReflection(module, fullName, null); - if (tr is null) - return fullName; - var asmRef = tr.DefinitionAssembly; - if (asmRef is null) - return fullName; - - var newFullName = fullName; - - string assemblyName = GetRealAssemblyName(asmRef); - if (!string.IsNullOrEmpty(assemblyName)) - newFullName = $"{tr.ReflectionFullName}, {assemblyName}"; - - return newFullName; - } - - string GetRealAssemblyName(IAssembly asm) { - string assemblyName = asm.FullName; - if (!asmNameToAsmFullName.TryGetValue(assemblyName, out var newAsmName)) - asmNameToAsmFullName[assemblyName] = newAsmName = TryGetRealAssemblyName(asm); - return newAsmName; - } - - string TryGetRealAssemblyName(IAssembly asm) { - var simpleName = asm.Name; - if (simpleName == module.CorLibTypes.AssemblyRef.Name) - return module.CorLibTypes.AssemblyRef.FullName; - - if (moduleMD is not null) { - var asmRef = moduleMD.GetAssemblyRef(simpleName); - if (asmRef is not null) - return asmRef.FullName; - } - - return GetAssemblyFullName(simpleName); - } - - /// - /// Converts an assembly simple name (eg. mscorlib) to the full name of the assembly, - /// which includes the version, public key token, etc. Returns null if it's - /// unknown. - /// - /// Simple name of assembly - /// - protected virtual string GetAssemblyFullName(string simpleName) => null; - - /// - /// Gets all types sorted by - /// - /// - public List GetSortedTypes() { - var list = new List(dict.Values); - list.Sort((a, b) => ((int)a.Code).CompareTo((int)b.Code)); - return list; - } - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceElement.cs b/Plugins/dnlib/DotNet/Resources/ResourceElement.cs deleted file mode 100644 index 4a4f1dc..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceElement.cs +++ /dev/null @@ -1,21 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Resources { - /// - /// Resource element - /// - public sealed class ResourceElement { - /// - /// Name of resource - /// - public string Name { get; set; } - - /// - /// Data of resource - /// - public IResourceData ResourceData { get; set; } - - /// - public override string ToString() => $"N: {Name}, V: {ResourceData}"; - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceElementSet.cs b/Plugins/dnlib/DotNet/Resources/ResourceElementSet.cs deleted file mode 100644 index ebb8da4..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceElementSet.cs +++ /dev/null @@ -1,115 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -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; } - - /// - /// The ResourceSet type name used by this set - /// - public string ResourceSetTypeName { get; } - - /// - /// The type of resource reader used to read this set - /// - public ResourceReaderType ReaderType { get; } - - /// - /// Format version of the resource set - /// - public int FormatVersion { get; internal set; } - - /// - /// Creates a new instance - /// - /// The ResourceReader type name to use - /// The ResourceSet type name to use - /// - internal ResourceElementSet(string resourceReaderTypeName, string resourceSetTypeName, ResourceReaderType readerType) { - ResourceReaderTypeName = resourceReaderTypeName; - ResourceSetTypeName = resourceSetTypeName; - ReaderType = readerType; - } - - /// - /// Gets the number of elements in the set - /// - public int Count => dict.Count; - - /// - /// Gets all resource elements - /// - 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; - - /// - /// Creates a new instance for a DeserializingResourceReader - /// - /// 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) { - FormatVersion = formatVersion - }; - } - - /// - /// Creates a new instance for a ResourceReader - /// - /// Module in which the set will reside - /// /// 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. - mscorlibFullName = module.CorLibTypes.AssemblyRef.FullName; - } - else { - // 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) { - FormatVersion = formatVersion - }; - } - - /// - /// Creates a new instance for a ResourceReader - /// - /// mscorlib assembly version - /// 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 - }; - } - - /// - /// Creates a new instance based on this instance - /// - /// - public ResourceElementSet Clone() => new ResourceElementSet(ResourceReaderTypeName, ResourceSetTypeName, ReaderType) { - FormatVersion = FormatVersion - }; - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceReader.cs b/Plugins/dnlib/DotNet/Resources/ResourceReader.cs deleted file mode 100644 index 8a35a14..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceReader.cs +++ /dev/null @@ -1,283 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Runtime.Serialization; -using System.Text; -using System.Text.RegularExpressions; -using dnlib.IO; - -namespace dnlib.DotNet.Resources { - /// - /// Thrown by - /// - [Serializable] - public sealed class ResourceReaderException : Exception { - /// - /// Constructor - /// - public ResourceReaderException() { - } - - /// - /// Constructor - /// - /// Message - public ResourceReaderException(string msg) - : base(msg) { - } - - /// - /// Constructor - /// - /// - /// - public ResourceReaderException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Gets called to create a from serialized data. Returns null - /// if a default instance should be created. - /// - /// ResourceDataFactory - /// Serialized type - /// Serialized data - /// Format of the serialized data - /// - public delegate IResourceData CreateResourceDataDelegate(ResourceDataFactory resourceDataFactory, UserResourceType type, byte[] serializedData, SerializationFormat format); - - /// - /// Reads .NET resources - /// - public struct ResourceReader { - DataReader reader; - readonly uint baseFileOffset; - readonly ResourceDataFactory resourceDataFactory; - readonly CreateResourceDataDelegate createResourceDataDelegate; - - ResourceReader(ResourceDataFactory resourceDataFactory, ref DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) { - this.reader = reader; - this.resourceDataFactory = resourceDataFactory; - this.createResourceDataDelegate = createResourceDataDelegate; - baseFileOffset = reader.StartOffset; - } - - /// - /// Returns true if it's possibly resources file data - /// - /// Reader - /// - public static bool CouldBeResourcesFile(DataReader reader) => - reader.CanRead(4U) && reader.ReadUInt32() == 0xBEEFCACE; - - /// - /// Reads a .NET resource - /// - /// Owner module - /// Data of resource - /// - public static ResourceElementSet Read(ModuleDef module, DataReader reader) => Read(module, reader, null); - - /// - /// Reads a .NET resource - /// - /// Owner module - /// Data of resource - /// Call back that gets called to create a instance. Can be null. - /// - public static ResourceElementSet Read(ModuleDef module, DataReader reader, CreateResourceDataDelegate createResourceDataDelegate) => - 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(); - if (sig != 0xBEEFCACE) - throw new ResourceReaderException($"Invalid resource sig: {sig:X8}"); - var resources = ReadHeader(); - if (resources is null) - throw new ResourceReaderException("Invalid resource reader"); - 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}"); - int numUserTypes = reader.ReadInt32(); - if (numUserTypes < 0) - throw new ResourceReaderException($"Invalid number of user types: {numUserTypes}"); - - var userTypes = new List(); - for (int i = 0; i < numUserTypes; i++) - userTypes.Add(new UserResourceType(reader.ReadSerializedString(), ResourceTypeCode.UserTypes + i)); - reader.Position = (reader.Position + 7) & ~7U; - - var hashes = new int[numResources]; - for (int i = 0; i < numResources; i++) - hashes[i] = reader.ReadInt32(); - var offsets = new int[numResources]; - for (int i = 0; i < numResources; i++) - offsets[i] = reader.ReadInt32(); - - long baseOffset = reader.Position; - long dataBaseOffset = reader.ReadInt32(); - long nameBaseOffset = reader.Position; - long end = reader.Length; - - var infos = new List(numResources); - - for (int i = 0; i < numResources; i++) { - reader.Position = (uint)(nameBaseOffset + offsets[i]); - var name = reader.ReadSerializedString(Encoding.Unicode); - long offset = dataBaseOffset + reader.ReadInt32(); - infos.Add(new ResourceInfo(name, offset)); - } - - infos.Sort((a, b) => a.offset.CompareTo(b.offset)); - for (int i = 0; i < infos.Count; i++) { - var info = infos[i]; - var element = new ResourceElement(); - element.Name = info.name; - reader.Position = (uint)info.offset; - long nextDataOffset = i == infos.Count - 1 ? end : infos[i + 1].offset; - int size = (int)(nextDataOffset - info.offset); - 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; - - resources.Add(element); - } - - return resources; - } - - sealed class ResourceInfo { - public readonly string name; - public readonly long offset; - public ResourceInfo(string name, long offset) { - this.name = name; - this.offset = offset; - } - public override string ToString() => $"{offset:X8} - {name}"; - } - - IResourceData ReadResourceDataV2(List userTypes, ResourceReaderType readerType, int size) { - uint endPos = reader.Position + (uint)size; - uint code = reader.Read7BitEncodedUInt32(); - switch ((ResourceTypeCode)code) { - 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) - throw new ResourceReaderException($"Invalid resource data code: {code}"); - return ReadSerializedObject(endPos, readerType, userTypes[userTypeIndex]); - } - } - - IResourceData ReadResourceDataV1(List userTypes, ResourceReaderType readerType, int size) { - uint endPos = reader.Position + (uint)size; - int typeIndex = reader.Read7BitEncodedInt32(); - 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, readerType, type); - } - } - - 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(); - 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); - res = createResourceDataDelegate?.Invoke(resourceDataFactory, type, serializedData, format); - return res ?? resourceDataFactory.CreateSerialized(serializedData, format, type); - } - default: - throw new ResourceReaderException($"Invalid reader type: {readerType}"); - } - } - - ResourceElementSet ReadHeader() { - 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}"); - - string resourceReaderTypeName = reader.ReadSerializedString(); - string resourceSetTypeName = reader.ReadSerializedString(); - - 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 new ResourceElementSet(resourceReaderTypeName, resourceSetTypeName, readerType); - } - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceReaderType.cs b/Plugins/dnlib/DotNet/Resources/ResourceReaderType.cs deleted file mode 100644 index 328eb4c..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceReaderType.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace dnlib.DotNet.Resources { - /// - /// Resource reader type - /// - public enum ResourceReaderType { - /// - /// System.Resources.ResourceReader - /// - ResourceReader, - /// - /// System.Resources.Extensions.DeserializingResourceReader - /// - DeserializingResourceReader, - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceTypeCode.cs b/Plugins/dnlib/DotNet/Resources/ResourceTypeCode.cs deleted file mode 100644 index ececc65..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceTypeCode.cs +++ /dev/null @@ -1,108 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Resources { - /// - /// Type of resource - /// - public enum ResourceTypeCode { - /// - /// null - /// - Null = 0, - - /// - /// - /// - String = 1, - - /// - /// - /// - Boolean = 2, - - /// - /// - /// - Char = 3, - - /// - /// - /// - Byte = 4, - - /// - /// - /// - SByte = 5, - - /// - /// - /// - Int16 = 6, - - /// - /// - /// - UInt16 = 7, - - /// - /// - /// - Int32 = 8, - - /// - /// - /// - UInt32 = 9, - - /// - /// - /// - Int64 = 0x0A, - - /// - /// - /// - UInt64 = 0x0B, - - /// - /// - /// - Single = 0x0C, - - /// - /// - /// - Double = 0x0D, - - /// - /// - /// - Decimal = 0x0E, - - /// - /// - /// - DateTime = 0x0F, - - /// - /// - /// - TimeSpan = 0x10, - - /// - /// array - /// - ByteArray = 0x20, - - /// - /// - /// - Stream = 0x21, - - /// - /// Start of user types - /// - UserTypes = 0x40, - } -} diff --git a/Plugins/dnlib/DotNet/Resources/ResourceWriter.cs b/Plugins/dnlib/DotNet/Resources/ResourceWriter.cs deleted file mode 100644 index 4130390..0000000 --- a/Plugins/dnlib/DotNet/Resources/ResourceWriter.cs +++ /dev/null @@ -1,161 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Runtime.Serialization.Formatters.Binary; -using System.Text; - -namespace dnlib.DotNet.Resources { - /// - /// Writes .NET resources - /// - public sealed class ResourceWriter { - ModuleDef module; - BinaryWriter writer; - ResourceElementSet resources; - ResourceDataFactory typeCreator; - Dictionary dataToNewType = new Dictionary(); - - ResourceWriter(ModuleDef module, ResourceDataFactory typeCreator, Stream stream, ResourceElementSet resources) { - this.module = module; - this.typeCreator = typeCreator; - writer = new BinaryWriter(stream); - this.resources = resources; - } - - /// - /// Write .NET resources - /// - /// Owner module - /// Output stream - /// .NET resources - public static void Write(ModuleDef module, Stream stream, ResourceElementSet resources) => - 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() { - if (resources.FormatVersion != 1 && resources.FormatVersion != 2) - throw new ArgumentException($"Invalid format version: {resources.FormatVersion}", nameof(resources)); - - InitializeUserTypes(resources.FormatVersion); - - writer.Write(0xBEEFCACE); - writer.Write(1); - WriteReaderType(); - writer.Write(resources.FormatVersion); - writer.Write(resources.Count); - writer.Write(typeCreator.Count); - foreach (var userType in typeCreator.GetSortedTypes()) - writer.Write(userType.Name); - int extraBytes = 8 - ((int)writer.BaseStream.Position & 7); - if (extraBytes != 8) { - for (int i = 0; i < extraBytes; i++) - writer.Write((byte)'X'); - } - - var nameOffsetStream = new MemoryStream(); - var nameOffsetWriter = new BinaryWriter(nameOffsetStream, Encoding.Unicode); - var dataStream = new MemoryStream(); - var dataWriter = new ResourceBinaryWriter(dataStream) { - FormatVersion = resources.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)); - int index = 0; - foreach (var info in resources.ResourceElements) { - offsets[index] = (int)nameOffsetWriter.BaseStream.Position; - hashes[index] = (int)Hash(info.Name); - index++; - nameOffsetWriter.Write(info.Name); - nameOffsetWriter.Write((int)dataWriter.BaseStream.Position); - WriteData(dataWriter, info, formatter); - } - - Array.Sort(hashes, offsets); - foreach (var hash in hashes) - writer.Write(hash); - foreach (var offset in offsets) - writer.Write(offset); - writer.Write((int)writer.BaseStream.Position + (int)nameOffsetStream.Length + 4); - writer.Write(nameOffsetStream.ToArray()); - writer.Write(dataStream.ToArray()); - } - - void WriteData(ResourceBinaryWriter writer, ResourceElement info, IFormatter formatter) { - var code = GetResourceType(info.ResourceData, writer.FormatVersion); - writer.Write7BitEncodedInt((int)code); - info.ResourceData.WriteData(writer, formatter); - } - - 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; - - return dataToNewType[data].Code; - } - - static uint Hash(string key) { - uint val = 0x1505; - foreach (var c in key) - val = ((val << 5) + val) ^ (uint)c; - return val; - } - - void InitializeUserTypes(int formatVersion) { - foreach (var resource in resources.ResourceElements) { - 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; - dataToNewType[resource.ResourceData] = newType; - } - } - - void WriteReaderType() { - var memStream = new MemoryStream(); - var headerWriter = new BinaryWriter(memStream); - 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()); - } - - string GetMscorlibFullname() { - if (module.CorLibTypes.AssemblyRef.Name == "mscorlib") - return module.CorLibTypes.AssemblyRef.FullName; - return "mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"; - } - } -} diff --git a/Plugins/dnlib/DotNet/Resources/UserResourceData.cs b/Plugins/dnlib/DotNet/Resources/UserResourceData.cs deleted file mode 100644 index 3083f5c..0000000 --- a/Plugins/dnlib/DotNet/Resources/UserResourceData.cs +++ /dev/null @@ -1,114 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.Serialization; -using dnlib.IO; - -namespace dnlib.DotNet.Resources { - /// - /// Base class of all user data - /// - public abstract class UserResourceData : IResourceData { - readonly UserResourceType type; - - /// - /// Full name including assembly of type - /// - public string TypeName => type.Name; - - /// - /// User type code - /// - public ResourceTypeCode Code => type.Code; - - /// - public FileOffset StartOffset { get; set; } - - /// - public FileOffset EndOffset { get; set; } - - /// - /// Constructor - /// - /// User resource type - public UserResourceData(UserResourceType type) => this.type = type; - - /// - public abstract void WriteData(ResourceBinaryWriter writer, IFormatter formatter); - } - - /// - /// Binary data - /// - 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, SerializationFormat format) - : base(type) { - this.data = data; - this.format = format; - } - - /// - public override void WriteData(ResourceBinaryWriter writer, IFormatter formatter) { - if (writer.ReaderType == ResourceReaderType.ResourceReader && format != SerializationFormat.BinaryFormatter) - throw new NotSupportedException($"Unsupported serialization format: {format} for {writer.ReaderType}"); - - if (writer.ReaderType == ResourceReaderType.DeserializingResourceReader) { - writer.Write7BitEncodedInt((int)format); - writer.Write7BitEncodedInt(data.Length); - } - writer.Write(data); - } - - /// - 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, - } -} diff --git a/Plugins/dnlib/DotNet/Resources/UserResourceType.cs b/Plugins/dnlib/DotNet/Resources/UserResourceType.cs deleted file mode 100644 index fde5524..0000000 --- a/Plugins/dnlib/DotNet/Resources/UserResourceType.cs +++ /dev/null @@ -1,34 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Resources { - /// - /// User resource type - /// - public sealed class UserResourceType { - readonly string name; - readonly ResourceTypeCode code; - - /// - /// Full name including assembly of type - /// - public string Name => name; - - /// - /// User type code - /// - public ResourceTypeCode Code => code; - - /// - /// Constructor - /// - /// Full name including assembly of type - /// User type code - public UserResourceType(string name, ResourceTypeCode code) { - this.name = name; - this.code = code; - } - - /// - public override string ToString() => $"{(int)code:X2} {name}"; - } -} diff --git a/Plugins/dnlib/DotNet/SecurityAction.cs b/Plugins/dnlib/DotNet/SecurityAction.cs deleted file mode 100644 index e93ba39..0000000 --- a/Plugins/dnlib/DotNet/SecurityAction.cs +++ /dev/null @@ -1,53 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Security action. See CorHdr.h/CorDeclSecurity - /// - public enum SecurityAction : short { - /// Mask allows growth of enum. - ActionMask = 0x001F, - /// - ActionNil = 0x0000, - /// - Request = 0x0001, - /// - Demand = 0x0002, - /// - Assert = 0x0003, - /// - Deny = 0x0004, - /// - PermitOnly = 0x0005, - /// - LinktimeCheck = 0x0006, - /// - LinkDemand = LinktimeCheck, - /// - InheritanceCheck = 0x0007, - /// - InheritDemand = InheritanceCheck, - /// - RequestMinimum = 0x0008, - /// - RequestOptional = 0x0009, - /// - RequestRefuse = 0x000A, - /// Persisted grant set at prejit time - PrejitGrant = 0x000B, - /// Persisted grant set at prejit time - PreJitGrant = PrejitGrant, - /// Persisted denied set at prejit time - PrejitDenied = 0x000C, - /// Persisted denied set at prejit time - PreJitDeny = PrejitDenied, - /// - NonCasDemand = 0x000D, - /// - NonCasLinkDemand = 0x000E, - /// - NonCasInheritance = 0x000F, - /// Maximum legal value - MaximumValue = 0x000F, - } -} diff --git a/Plugins/dnlib/DotNet/SecurityAttribute.cs b/Plugins/dnlib/DotNet/SecurityAttribute.cs deleted file mode 100644 index fbbfa03..0000000 --- a/Plugins/dnlib/DotNet/SecurityAttribute.cs +++ /dev/null @@ -1,113 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// A DeclSecurity security attribute - /// - public sealed class SecurityAttribute : ICustomAttribute { - ITypeDefOrRef attrType; - readonly IList namedArguments; - - /// - /// Gets/sets the attribute type - /// - public ITypeDefOrRef AttributeType { - get => attrType; - set => attrType = value; - } - - /// - /// Gets the full name of the attribute type - /// - public string TypeFullName { - get { - var at = attrType; - return at is null ? string.Empty : at.FullName; - } - } - - /// - /// Gets all named arguments (field and property values) - /// - public IList NamedArguments => namedArguments; - - /// - /// true if is not empty - /// - public bool HasNamedArguments => namedArguments.Count > 0; - - /// - /// Gets all s that are field arguments - /// - public IEnumerable Fields { - get { - 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; - } - } - } - - /// - /// Gets all s that are property arguments - /// - public IEnumerable Properties { - get { - 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; - } - } - } - - /// - /// Creates a from an XML string. - /// - /// Owner module - /// XML - /// A new instance - public static SecurityAttribute CreateFromXml(ModuleDef module, string xml) { - var attrType = module.CorLibTypes.GetTypeRef("System.Security.Permissions", "PermissionSetAttribute"); - var utf8Xml = new UTF8String(xml); - var namedArg = new CANamedArgument(false, module.CorLibTypes.String, "XML", new CAArgument(module.CorLibTypes.String, utf8Xml)); - var list = new List { namedArg }; - return new SecurityAttribute(attrType, list); - } - - /// - /// Default constructor - /// - public SecurityAttribute() - : this(null, null) { - } - - /// - /// Constructor - /// - /// Attribute type - public SecurityAttribute(ITypeDefOrRef attrType) - : this(attrType, null) { - } - - /// - /// Constructor - /// - /// Attribute type - /// Named arguments that will be owned by this instance - public SecurityAttribute(ITypeDefOrRef attrType, IList namedArguments) { - this.attrType = attrType; - this.namedArguments = namedArguments ?? new List(); - } - - /// - public override string ToString() => TypeFullName; - } -} diff --git a/Plugins/dnlib/DotNet/SerializationType.cs b/Plugins/dnlib/DotNet/SerializationType.cs deleted file mode 100644 index 59a4680..0000000 --- a/Plugins/dnlib/DotNet/SerializationType.cs +++ /dev/null @@ -1,49 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// See CorSerializationType/CorHdr.h - /// - enum SerializationType : byte { - /// - Undefined = 0, - /// System.Boolean - Boolean = ElementType.Boolean, - /// System.Char - Char = ElementType.Char, - /// System.SByte - I1 = ElementType.I1, - /// System.Byte - U1 = ElementType.U1, - /// System.Int16 - I2 = ElementType.I2, - /// System.UInt16 - U2 = ElementType.U2, - /// System.Int32 - I4 = ElementType.I4, - /// System.UInt32 - U4 = ElementType.U4, - /// System.Int64 - I8 = ElementType.I8, - /// System.UInt64 - U8 = ElementType.U8, - /// System.Single - R4 = ElementType.R4, - /// System.Double - R8 = ElementType.R8, - /// System.String - String = ElementType.String, - /// Single-dimension, zero lower bound array ([]) - SZArray = ElementType.SZArray, - /// System.Type - Type = 0x50, - /// Boxed value type - TaggedObject= 0x51, - /// A field - Field = 0x53, - /// A property - Property = 0x54, - /// An enum - Enum = 0x55, - } -} diff --git a/Plugins/dnlib/DotNet/SigComparer.cs b/Plugins/dnlib/DotNet/SigComparer.cs deleted file mode 100644 index 5fbfca7..0000000 --- a/Plugins/dnlib/DotNet/SigComparer.cs +++ /dev/null @@ -1,4732 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Reflection; - -namespace dnlib.DotNet { - /// - /// Compares types - /// - public sealed class TypeEqualityComparer : IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Default instance - /// - public static readonly TypeEqualityComparer Instance = new TypeEqualityComparer(0); - - /// - /// Case insensitive names - /// - 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 - /// - /// Comparison options - public TypeEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(IType x, IType y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(IType obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(ITypeDefOrRef x, ITypeDefOrRef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(ITypeDefOrRef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(TypeRef x, TypeRef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(TypeRef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(TypeDef x, TypeDef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(TypeDef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(TypeSpec x, TypeSpec y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(TypeSpec obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(TypeSig x, TypeSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(TypeSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(ExportedType x, ExportedType y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(ExportedType obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Compares fields - /// - public sealed class FieldEqualityComparer : IEqualityComparer, IEqualityComparer, IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Compares the declaring types - /// - public static readonly FieldEqualityComparer CompareDeclaringTypes = new FieldEqualityComparer(SigComparerOptions.CompareMethodFieldDeclaringType); - - /// - /// Doesn't compare the declaring types - /// - public static readonly FieldEqualityComparer DontCompareDeclaringTypes = new FieldEqualityComparer(0); - - /// - /// Compares the declaring types, case insensitive names - /// - public static readonly FieldEqualityComparer CaseInsensitiveCompareDeclaringTypes = new FieldEqualityComparer(SigComparerOptions.CompareMethodFieldDeclaringType | SigComparerOptions.CaseInsensitiveAll); - - /// - /// Doesn't compare the declaring types, case insensitive names - /// - 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 - /// - /// Comparison options - public FieldEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(IField x, IField y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(IField obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(FieldDef x, FieldDef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(FieldDef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MemberRef x, MemberRef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MemberRef obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Compares methods - /// - public sealed class MethodEqualityComparer : IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Compares the declaring types - /// - public static readonly MethodEqualityComparer CompareDeclaringTypes = new MethodEqualityComparer(SigComparerOptions.CompareMethodFieldDeclaringType); - - /// - /// Doesn't compare the declaring types - /// - public static readonly MethodEqualityComparer DontCompareDeclaringTypes = new MethodEqualityComparer(0); - - /// - /// Compares the declaring types, case insensitive names - /// - public static readonly MethodEqualityComparer CaseInsensitiveCompareDeclaringTypes = new MethodEqualityComparer(SigComparerOptions.CompareMethodFieldDeclaringType | SigComparerOptions.CaseInsensitiveAll); - - /// - /// Doesn't compare the declaring types, case insensitive names - /// - 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 - /// - /// Comparison options - public MethodEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(IMethod x, IMethod y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(IMethod obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(IMethodDefOrRef x, IMethodDefOrRef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(IMethodDefOrRef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MethodDef x, MethodDef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MethodDef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MemberRef x, MemberRef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MemberRef obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MethodSpec x, MethodSpec y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MethodSpec obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Compares properties - /// - public sealed class PropertyEqualityComparer : IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Compares the declaring types - /// - public static readonly PropertyEqualityComparer CompareDeclaringTypes = new PropertyEqualityComparer(SigComparerOptions.ComparePropertyDeclaringType); - - /// - /// Doesn't compare the declaring types - /// - public static readonly PropertyEqualityComparer DontCompareDeclaringTypes = new PropertyEqualityComparer(0); - - /// - /// Compares the declaring types, case insensitive names - /// - public static readonly PropertyEqualityComparer CaseInsensitiveCompareDeclaringTypes = new PropertyEqualityComparer(SigComparerOptions.ComparePropertyDeclaringType | SigComparerOptions.CaseInsensitiveAll); - - /// - /// Doesn't compare the declaring types, case insensitive names - /// - 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 - /// - /// Comparison options - public PropertyEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(PropertyDef x, PropertyDef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(PropertyDef obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Compares events - /// - public sealed class EventEqualityComparer : IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Compares the declaring types - /// - public static readonly EventEqualityComparer CompareDeclaringTypes = new EventEqualityComparer(SigComparerOptions.CompareEventDeclaringType); - - /// - /// Doesn't compare the declaring types - /// - public static readonly EventEqualityComparer DontCompareDeclaringTypes = new EventEqualityComparer(0); - - /// - /// Compares the declaring types, case insensitive names - /// - public static readonly EventEqualityComparer CaseInsensitiveCompareDeclaringTypes = new EventEqualityComparer(SigComparerOptions.CompareEventDeclaringType | SigComparerOptions.CaseInsensitiveAll); - - /// - /// Doesn't compare the declaring types, case insensitive names - /// - 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 - /// - /// Comparison options - public EventEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(EventDef x, EventDef y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(EventDef obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Compares calling convention signatures - /// - public sealed class SignatureEqualityComparer : IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer, IEqualityComparer { - readonly SigComparerOptions options; - - /// - /// Default instance - /// - public static readonly SignatureEqualityComparer Instance = new SignatureEqualityComparer(0); - - /// - /// Case insensitive names - /// - public static readonly SignatureEqualityComparer CaseInsensitive = new SignatureEqualityComparer(SigComparerOptions.CaseInsensitiveAll); - - /// - /// Constructor - /// - /// Comparison options - public SignatureEqualityComparer(SigComparerOptions options) => this.options = options; - - /// - public bool Equals(CallingConventionSig x, CallingConventionSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(CallingConventionSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MethodBaseSig x, MethodBaseSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MethodBaseSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(MethodSig x, MethodSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(MethodSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(PropertySig x, PropertySig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(PropertySig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(FieldSig x, FieldSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(FieldSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(LocalSig x, LocalSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(LocalSig obj) => new SigComparer(options).GetHashCode(obj); - - /// - public bool Equals(GenericInstMethodSig x, GenericInstMethodSig y) => new SigComparer(options).Equals(x, y); - - /// - public int GetHashCode(GenericInstMethodSig obj) => new SigComparer(options).GetHashCode(obj); - } - - /// - /// Decides how to compare types, sigs, etc - /// - [Flags] - public enum SigComparerOptions : uint { - /// - /// Don't compare a type's (assembly/module) scope - /// - DontCompareTypeScope = 1, - - /// - /// Compares a method/field's declaring type. - /// - CompareMethodFieldDeclaringType = 2, - - /// - /// Compares a property's declaring type - /// - ComparePropertyDeclaringType = 4, - - /// - /// Compares an event's declaring type - /// - CompareEventDeclaringType = 8, - - /// - /// Compares method / field / property / event declaring types - /// - CompareDeclaringTypes = CompareMethodFieldDeclaringType | ComparePropertyDeclaringType | CompareEventDeclaringType, - - /// - /// Compares parameters after a sentinel in method sigs. Should not be enabled when - /// comparing s against s since it's - /// not possible to get those sentinel params from a . - /// - CompareSentinelParams = 0x10, - - /// - /// Compares assembly public key token - /// - CompareAssemblyPublicKeyToken = 0x20, - - /// - /// Compares assembly version - /// - CompareAssemblyVersion = 0x40, - - /// - /// Compares assembly locale - /// - CompareAssemblyLocale = 0x80, - - /// - /// If set, a and an can reference the - /// global <Module> type. - /// - TypeRefCanReferenceGlobalType = 0x100, - - /// - /// Don't compare a method/property's return type - /// - DontCompareReturnType = 0x200, - - // Internal only - //SubstituteGenericParameters = 0x400, - - /// - /// Type namespaces are case insensitive - /// - CaseInsensitiveTypeNamespaces = 0x800, - - /// - /// Type names (not namespaces) are case insensitive - /// - CaseInsensitiveTypeNames = 0x1000, - - /// - /// Type names and namespaces are case insensitive - /// - CaseInsensitiveTypes = CaseInsensitiveTypeNamespaces | CaseInsensitiveTypeNames, - - /// - /// Method and field names are case insensitive - /// - CaseInsensitiveMethodFieldNames = 0x2000, - - /// - /// Property names are case insensitive - /// - CaseInsensitivePropertyNames = 0x4000, - - /// - /// Event names are case insensitive - /// - CaseInsensitiveEventNames = 0x8000, - - /// - /// Type namespaces, type names, method names, field names, property names - /// and event names are all case insensitive - /// - CaseInsensitiveAll = CaseInsensitiveTypeNamespaces | CaseInsensitiveTypeNames | - CaseInsensitiveMethodFieldNames | CaseInsensitivePropertyNames | - CaseInsensitiveEventNames, - - /// - /// A field that is can compare equal to - /// a - /// - PrivateScopeFieldIsComparable = 0x10000, - - /// - /// A method that is can compare equal to - /// a - /// - PrivateScopeMethodIsComparable = 0x20000, - - /// - /// A field that is and a method that is - /// can compare equal to a - /// - PrivateScopeIsComparable = PrivateScopeFieldIsComparable | PrivateScopeMethodIsComparable, - - /// - /// Raw (bit by bit) comparison of signatures. This matches what the CLR does when it - /// compares signatures. This means that metadata tokens will be compared. - /// - RawSignatureCompare = 0x40000, - - /// - /// Ignore required and optional modifiers when comparing s. - /// They're already ignored when comparing eg. a with a - /// . - /// - IgnoreModifiers = 0x80000, - - /// - /// 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 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, - - /// - /// Don't project CLR compatible WinMD references back to the original CLR type/method before comparing - /// - DontProjectWinMDRefs = 0x200000, - - /// - /// 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, - - /// - /// When comparing types, don't compare a multi-dimensional array's lower bounds and sizes - /// - IgnoreMultiDimensionalArrayLowerBoundsAndSizes = 0x800000, - - /// - /// When comparing MemberDefs in same module, use regular reference comparison instead - /// comparing the signature, name, and other properties. - /// - ReferenceCompareForMemberDefsInSameModule = 0x1000000, - } - - /// - /// Compares types, signatures, methods, fields, properties, events - /// - public struct SigComparer { - const SigComparerOptions SigComparerOptions_DontSubstituteGenericParameters = (SigComparerOptions)0x400; - - const int HASHCODE_MAGIC_GLOBAL_TYPE = 1654396648; - const int HASHCODE_MAGIC_NESTED_TYPE = -1049070942; - const int HASHCODE_MAGIC_ET_MODULE = -299744851; - const int HASHCODE_MAGIC_ET_VALUEARRAY = -674970533; - const int HASHCODE_MAGIC_ET_GENERICINST = -2050514639; - const int HASHCODE_MAGIC_ET_VAR = 1288450097; - const int HASHCODE_MAGIC_ET_MVAR = -990598495; - const int HASHCODE_MAGIC_ET_ARRAY = -96331531; - const int HASHCODE_MAGIC_ET_SZARRAY = 871833535; - const int HASHCODE_MAGIC_ET_BYREF = -634749586; - const int HASHCODE_MAGIC_ET_PTR = 1976400808; - const int HASHCODE_MAGIC_ET_SENTINEL = 68439620; - - RecursionCounter recursionCounter; - SigComparerOptions options; - GenericArguments genericArguments; - readonly ModuleDef sourceModule; - - 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 DontSubstituteGenericParameters => (options & SigComparerOptions_DontSubstituteGenericParameters) != 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; - bool IgnoreMultiDimensionalArrayLowerBoundsAndSizes => (options & SigComparerOptions.IgnoreMultiDimensionalArrayLowerBoundsAndSizes) != 0; - bool ReferenceCompareForMemberDefsInSameModule => (options & SigComparerOptions.ReferenceCompareForMemberDefsInSameModule) != 0; - - /// - /// Constructor - /// - /// Comparison options - public SigComparer(SigComparerOptions options) - : this(options, null) { - } - - /// - /// Constructor - /// - /// Comparison options - /// The module which the comparison take place in. - public SigComparer(SigComparerOptions options, ModuleDef sourceModule) { - recursionCounter = new RecursionCounter(); - this.options = options; - genericArguments = null; - this.sourceModule = sourceModule; - } - - /// - /// is mapped to , so use - /// the same hash code for both - /// - int GetHashCode_FnPtr_SystemIntPtr() { - // ******************************************** - // IMPORTANT: This must match GetHashCode(TYPE) - // ******************************************** - - return GetHashCode_TypeNamespace("System") + - GetHashCode_TypeName("IntPtr"); - } - - bool Equals_Names(bool caseInsensitive, UTF8String a, UTF8String b) { - if (caseInsensitive) - return UTF8String.ToSystemStringOrEmpty(a).Equals(UTF8String.ToSystemStringOrEmpty(b), StringComparison.OrdinalIgnoreCase); - return UTF8String.Equals(a, b); - } - - bool Equals_Names(bool caseInsensitive, string a, string b) { - if (caseInsensitive) - return (a ?? string.Empty).Equals(b ?? string.Empty, StringComparison.OrdinalIgnoreCase); - return (a ?? string.Empty) == (b ?? string.Empty); - } - - int GetHashCode_Name(bool caseInsensitive, string a) { - if (caseInsensitive) - return (a ?? string.Empty).ToUpperInvariant().GetHashCode(); - return (a ?? string.Empty).GetHashCode(); - } - - 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; - options &= ~flags; - return old; - } - - SigComparerOptions SetOptions(SigComparerOptions flags) { - var old = options; - options |= flags; - return old; - } - - void RestoreOptions(SigComparerOptions oldFlags) => options = oldFlags; - - void InitializeGenericArguments() { - if (genericArguments is null) - genericArguments = new GenericArguments(); - } - - static GenericInstSig GetGenericInstanceType(IMemberRefParent parent) { - var ts = parent as TypeSpec; - if (ts is null) - return null; - return ts.TypeSig.RemoveModifiers() as GenericInstSig; - } - - bool Equals(IAssembly aAsm, IAssembly bAsm, TypeRef b) { - if (Equals(aAsm, bAsm)) - return true; - - // Could be an exported type. Resolve it and check again. - - var td = b.Resolve(sourceModule); - return td is not null && Equals(aAsm, td.Module.Assembly); - } - - bool Equals(IAssembly aAsm, IAssembly bAsm, ExportedType b) { - if (Equals(aAsm, bAsm)) - return true; - - var td = b.Resolve(); - return td is not null && Equals(aAsm, td.Module.Assembly); - } - - bool Equals(IAssembly aAsm, TypeRef a, IAssembly bAsm, TypeRef b) { - if (Equals(aAsm, bAsm)) - return true; - - // Could be exported types. Resolve them and check again. - - var tda = a.Resolve(sourceModule); - var tdb = b.Resolve(sourceModule); - 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) { - if (Equals(aAsm, bAsm)) - return true; - - var tda = a.Resolve(); - var tdb = b.Resolve(); - 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) { - if (Equals(aAsm, bAsm)) - return true; - - // Could be an exported type. Resolve it and check again. - - var tda = a.Resolve(sourceModule); - var tdb = b.Resolve(); - return tda is not null && tdb is not null && Equals(tda.Module.Assembly, tdb.Module.Assembly); - } - - bool Equals(TypeDef a, IModule bMod, TypeRef b) { - if (Equals(a.Module, bMod) && Equals(a.DefinitionAssembly, b.DefinitionAssembly)) - return true; - - // Could be an exported type. Resolve it and check again. - - var td = b.Resolve(sourceModule); - if (td is null) - return false; - if (!DontCheckTypeEquivalence) { - if (TIAHelper.Equivalent(a, td)) - return true; - } - return Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); - } - - bool Equals(TypeDef a, FileDef bFile, ExportedType b) { - if (Equals(a.Module, bFile) && Equals(a.DefinitionAssembly, b.DefinitionAssembly)) - return true; - - var td = b.Resolve(); - return td is not null && Equals(a.Module, td.Module) && Equals(a.DefinitionAssembly, td.DefinitionAssembly); - } - - bool TypeDefScopeEquals(TypeDef a, TypeDef b) { - if (a is null || b is null) - return false; - if (!DontCheckTypeEquivalence) { - if (TIAHelper.Equivalent(a, b)) - return true; - } - return Equals(a.Module, b.Module); - } - - bool Equals(TypeRef a, IModule ma, TypeRef b, IModule mb) { - if (Equals(ma, mb) && Equals(a.DefinitionAssembly, b.DefinitionAssembly)) - return true; - - // Could be exported types. Resolve them and check again. - - var tda = a.Resolve(sourceModule); - var tdb = b.Resolve(sourceModule); - return tda is not null && tdb is not null && - Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); - } - - bool Equals(TypeRef a, IModule ma, ExportedType b, FileDef fb) { - if (Equals(ma, fb) && Equals(a.DefinitionAssembly, b.DefinitionAssembly)) - return true; - - // Could be an exported type. Resolve it and check again. - - var tda = a.Resolve(sourceModule); - var tdb = b.Resolve(); - return tda is not null && tdb is not null && - Equals(tda.Module, tdb.Module) && Equals(tda.DefinitionAssembly, tdb.DefinitionAssembly); - } - - bool Equals(Assembly aAsm, IAssembly bAsm, TypeRef b) { - if (Equals(bAsm, aAsm)) - return true; - - // Could be an exported type. Resolve it and check again. - - var td = b.Resolve(sourceModule); - return td is not null && Equals(td.Module.Assembly, aAsm); - } - - bool Equals(Assembly aAsm, IAssembly bAsm, ExportedType b) { - if (Equals(bAsm, aAsm)) - return true; - - var td = b.Resolve(); - return td is not null && Equals(td.Module.Assembly, aAsm); - } - - bool Equals(Type a, IModule bMod, TypeRef b) { - if (Equals(bMod, a.Module) && Equals(b.DefinitionAssembly, a.Assembly)) - return true; - - // Could be an exported type. Resolve it and check again. - - var td = b.Resolve(sourceModule); - return td is not null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); - } - - bool Equals(Type a, FileDef bFile, ExportedType b) { - if (Equals(bFile, a.Module) && Equals(b.DefinitionAssembly, a.Assembly)) - return true; - - var td = b.Resolve(); - return td is not null && Equals(td.Module, a.Module) && Equals(td.DefinitionAssembly, a.Assembly); - } - - /// - /// Compare members - /// - /// Member #1 - /// Member #2 - /// true if same, false otherwise - public bool Equals(IMemberRef a, IMemberRef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - IType ta, tb; - IField fa, fb; - IMethod ma, mb; - PropertyDef pa, pb; - EventDef ea, eb; - - 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 not null && (fb = b as IField) is not null && fa.IsField && fb.IsField) - result = Equals(fa, fb); - 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 not null && (pb = b as PropertyDef) is not null) - result = Equals(pa, pb); - else if ((ea = a as EventDef) is not null && (eb = b as EventDef) is not null) - result = Equals(ea, eb); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a member - /// - /// The member - /// The hash code - public int GetHashCode(IMemberRef a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int result; - IType ta; - IField fa; - IMethod ma; - PropertyDef pa; - EventDef ea; - - if ((ta = a as IType) is not null) - result = GetHashCode(ta); - else if ((fa = a as IField) is not null) - result = GetHashCode(fa); - else if ((ma = a as IMethod) is not null) - result = GetHashCode(ma); - else if ((pa = a as PropertyDef) is not null) - result = GetHashCode(pa); - else if ((ea = a as EventDef) is not null) - result = GetHashCode(ea); - else - result = 0; // Should never be reached - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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) => GetHashCode((IType)a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(IType a, IType b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - TypeDef tda, tdb; - TypeRef tra, trb; - TypeSpec tsa, tsb; - TypeSig sa, sb; - ExportedType eta, etb; - - 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 not null & (trb = b as TypeRef) is not null) - result = Equals(tra, trb); - 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 not null & (sb = b as TypeSig) is not null) - result = Equals(sa, sb); - else if ((eta = a as ExportedType) is not null & (etb = b as ExportedType) is not null) - result = Equals(eta, etb); - else if (tda is not null && trb is not null) - result = Equals(tda, trb); // TypeDef vs TypeRef - else if (tra is not null && tdb is not null) - result = Equals(tdb, tra); // TypeDef vs TypeRef - else if (tda is not null && tsb is not null) - result = Equals(tda, tsb); // TypeDef vs TypeSpec - else if (tsa is not null && tdb is not null) - result = Equals(tdb, tsa); // TypeDef vs TypeSpec - else if (tda is not null && sb is not null) - result = Equals(tda, sb); // TypeDef vs TypeSig - else if (sa is not null && tdb is not null) - result = Equals(tdb, sa); // TypeDef vs TypeSig - else if (tda is not null && etb is not null) - result = Equals(tda, etb); // TypeDef vs ExportedType - else if (eta is not null && tdb is not null) - result = Equals(tdb, eta); // TypeDef vs ExportedType - else if (tra is not null && tsb is not null) - result = Equals(tra, tsb); // TypeRef vs TypeSpec - else if (tsa is not null && trb is not null) - result = Equals(trb, tsa); // TypeRef vs TypeSpec - else if (tra is not null && sb is not null) - result = Equals(tra, sb); // TypeRef vs TypeSig - else if (sa is not null && trb is not null) - result = Equals(trb, sa); // TypeRef vs TypeSig - else if (tra is not null && etb is not null) - result = Equals(tra, etb); // TypeRef vs ExportedType - else if (eta is not null && trb is not null) - result = Equals(trb, eta); // TypeRef vs ExportedType - else if (tsa is not null && sb is not null) - result = Equals(tsa, sb); // TypeSpec vs TypeSig - else if (sa is not null && tsb is not null) - result = Equals(tsb, sa); // TypeSpec vs TypeSig - else if (tsa is not null && etb is not null) - result = Equals(tsa, etb); // TypeSpec vs ExportedType - else if (eta is not null && tsb is not null) - result = Equals(tsb, eta); // TypeSpec vs ExportedType - else if (sa is not null && etb is not null) - result = Equals(sa, etb); // TypeSig vs ExportedType - else if (eta is not null && sb is not null) - result = Equals(sb, eta); // TypeSig vs ExportedType - else - result = false; // Should never be reached - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(IType a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash; - TypeDef td; - TypeRef tr; - TypeSpec ts; - TypeSig sig; - ExportedType et; - - if ((td = a as TypeDef) is not null) - hash = GetHashCode(td); - else if ((tr = a as TypeRef) is not null) - hash = GetHashCode(tr); - else if ((ts = a as TypeSpec) is not null) - hash = GetHashCode(ts); - else if ((sig = a as TypeSig) is not null) - hash = GetHashCode(sig); - else if ((et = a as ExportedType) is not null) - hash = GetHashCode(et); - else - hash = 0; // Should never be reached - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeRef a, TypeDef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeDef a, TypeRef b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - IModule bMod; - AssemblyRef bAsm; - TypeRef dtb; - - if (!DontProjectWinMDRefs) { - var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (tra is not null) { - result = Equals(tra, b); - goto exit; - } - } - - var scope = b.ResolutionScope; - - if (!Equals_TypeNames(a.Name, b.Name) || !Equals_TypeNamespaces(a.Namespace, b.Namespace)) - result = false; - else if ((dtb = scope as TypeRef) is not null) // nested type - result = Equals(a.DeclaringType, dtb); // Compare enclosing types - 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 not null) // 'b' is defined in the same assembly as 'a' - result = Equals(a, bMod, b); - else if ((bAsm = scope as AssemblyRef) is not null) { - var aMod = a.Module; - result = aMod is not null && Equals(aMod.Assembly, bAsm, b); - if (!result) { - if (!DontCheckTypeEquivalence) { - var tdb = b.Resolve(); - result = TypeDefScopeEquals(a, tdb); - } - } - } - else { - result = false; - //TODO: Handle the case where scope is null - } - - if (result && !TypeRefCanReferenceGlobalType && a.IsGlobalModuleType) - result = false; -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(ExportedType a, TypeDef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeDef a, ExportedType b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - ExportedType dtb; - FileDef bFile; - AssemblyRef bAsm; - if (!DontProjectWinMDRefs) { - var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (tra is not null) { - result = Equals(tra, b); - goto exit; - } - } - - var scope = b.Implementation; - - if (!Equals_TypeNames(a.Name, b.TypeName) || !Equals_TypeNamespaces(a.Namespace, b.TypeNamespace)) - result = false; - else if ((dtb = scope as ExportedType) is not null) { // nested type - result = Equals(a.DeclaringType, dtb); // Compare enclosing types - } - 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 not null) - result = Equals(a, bFile, b); - else if ((bAsm = scope as AssemblyRef) is not null) { - var aMod = a.Module; - result = aMod is not null && Equals(aMod.Assembly, bAsm, b); - } - else - result = false; - if (!result && !DontCheckTypeEquivalence) { - var tdb = b.Resolve(); - result = TypeDefScopeEquals(a, tdb); - } - } - - if (result && !TypeRefCanReferenceGlobalType && a.IsGlobalModuleType) - result = false; -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeDef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeDef a, TypeSpec b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a, b.TypeSig); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, TypeDef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeDef a, TypeSig b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - //************************************************************* - // If this code gets updated, update GetHashCode(TypeSig), - // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too - //************************************************************* - if (b is TypeDefOrRefSig b2) - result = Equals(a, (IType)b2.TypeDefOrRef); - else if (b is ModifierSig || b is PinnedSig) - result = Equals(a, b.Next); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeRef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeRef a, TypeSpec b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a, b.TypeSig); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(ExportedType a, TypeRef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeRef a, ExportedType b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - if (!DontProjectWinMDRefs) { - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - } - bool result = Equals_TypeNames(a.Name, b.TypeName) && - Equals_TypeNamespaces(a.Namespace, b.TypeNamespace) && - EqualsScope(a, b); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, TypeRef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeRef a, TypeSig b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - //************************************************************* - // If this code gets updated, update GetHashCode(TypeSig), - // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too - //************************************************************* - if (b is TypeDefOrRefSig b2) - result = Equals(a, (IType)b2.TypeDefOrRef); - else if (b is ModifierSig || b is PinnedSig) - result = Equals(a, b.Next); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, TypeSpec b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeSig b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a.TypeSig, b); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(ExportedType a, TypeSpec b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSpec a, ExportedType b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a.TypeSig, b); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(ExportedType a, TypeSig b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, ExportedType b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - //************************************************************* - // If this code gets updated, update GetHashCode(TypeSig), - // Equals(TypeRef,TypeSig) and Equals(TypeSig,ExportedType) too - //************************************************************* - if (a is TypeDefOrRefSig a2) - result = Equals(a2.TypeDefOrRef, b); - else if (a is ModifierSig || a is PinnedSig) - result = Equals(a.Next, b); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - int GetHashCodeGlobalType() { - // We don't always know the name+namespace of the global type, eg. when it's - // referenced by a ModuleRef. Use the same hash for all global types. - return HASHCODE_MAGIC_GLOBAL_TYPE; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeRef a, TypeRef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - if (!DontProjectWinMDRefs) { - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - } - bool result = Equals_TypeNames(a.Name, b.Name) && - Equals_TypeNamespaces(a.Namespace, b.Namespace) && - EqualsResolutionScope(a, b); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(TypeRef a) { - // ************************************************************************************ - // IMPORTANT: This hash code must match the Type/TypeRef/TypeDef/ExportedType - // hash code and GetHashCode_FnPtr_SystemIntPtr() method - // ************************************************************************************ - - // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a is null) - return TypeRefCanReferenceGlobalType ? GetHashCodeGlobalType() : 0; - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - - int hash; - hash = GetHashCode_TypeName(a.Name); - if (a.ResolutionScope is TypeRef) - hash += HASHCODE_MAGIC_NESTED_TYPE; - else - hash += GetHashCode_TypeNamespace(a.Namespace); - return hash; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(ExportedType a, ExportedType b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - if (!DontProjectWinMDRefs) { - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - } - bool result = Equals_TypeNames(a.TypeName, b.TypeName) && - Equals_TypeNamespaces(a.TypeNamespace, b.TypeNamespace) && - EqualsImplementation(a, b); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(ExportedType a) { - // ************************************************************************************ - // IMPORTANT: This hash code must match the Type/TypeRef/TypeDef/ExportedType - // hash code and GetHashCode_FnPtr_SystemIntPtr() method - // ************************************************************************************ - - // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a is null) - return TypeRefCanReferenceGlobalType ? GetHashCodeGlobalType() : 0; - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - int hash; - hash = GetHashCode_TypeName(a.TypeName); - if (a.Implementation is ExportedType) - hash += HASHCODE_MAGIC_NESTED_TYPE; - else - hash += GetHashCode_TypeNamespace(a.TypeNamespace); - return hash; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeDef a, TypeDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - - if (!DontProjectWinMDRefs) { - var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - var trb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (tra is not null || trb is not null) { - result = Equals((IType)tra ?? a, (IType)trb ?? b); - goto exit; - } - } - result = Equals_TypeNames(a.Name, b.Name) && - Equals_TypeNamespaces(a.Namespace, b.Namespace) && - Equals(a.DeclaringType, b.DeclaringType) && - (DontCompareTypeScope || TypeDefScopeEquals(a, b)); - -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(TypeDef a) { - // ************************************************************************************ - // IMPORTANT: This hash code must match the Type/TypeRef/TypeDef/ExportedType - // hash code and GetHashCode_FnPtr_SystemIntPtr() method - // ************************************************************************************ - - // See GetHashCode(Type) for the reason why null returns GetHashCodeGlobalType() - if (a is null || a.IsGlobalModuleType) - return GetHashCodeGlobalType(); - if (!DontProjectWinMDRefs) { - var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (tra is not null) - return GetHashCode(tra); - } - - int hash; - hash = GetHashCode_TypeName(a.Name); - if (a.DeclaringType is not null) - hash += HASHCODE_MAGIC_NESTED_TYPE; - else - hash += GetHashCode_TypeNamespace(a.Namespace); - return hash; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSpec a, TypeSpec b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals(a.TypeSig, b.TypeSig); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(TypeSpec a) { - if (a is null) - return 0; - return GetHashCode(a.TypeSig); - } - - /// - /// Compares resolution scopes - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - bool EqualsResolutionScope(TypeRef a, TypeRef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - var ra = a.ResolutionScope; - var rb = b.ResolutionScope; - if (ra == rb) - return true; - if (ra is null || rb is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - TypeRef ea, eb; - IModule ma, mb; - AssemblyRef aa, ab; - ModuleDef modDef; - bool resolveCheck = true; - - // if one of them is a TypeRef, the other one must be too - 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 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 not null & (ab = rb as AssemblyRef) is not null) - result = Equals(aa, a, ab, b); - else if (aa is not null && rb is ModuleRef) { - var bMod = b.Module; - result = bMod is not null && Equals(bMod.Assembly, b, aa, a); - } - else if (ab is not null && ra is ModuleRef) { - var aMod = a.Module; - result = aMod is not null && Equals(aMod.Assembly, a, ab, b); - } - else if (aa is not null && (modDef = rb as ModuleDef) is not null) - result = Equals(modDef.Assembly, aa, a); - else if (ab is not null && (modDef = ra as ModuleDef) is not null) - result = Equals(modDef.Assembly, ab, b); - else { - result = false; - resolveCheck = false; - } - if (!result && resolveCheck) { - if (!DontCheckTypeEquivalence) { - var td1 = a.Resolve(); - var td2 = b.Resolve(); - if (td1 is not null && td2 is not null) - result = TypeDefScopeEquals(td1, td2); - } - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares implementation - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - bool EqualsImplementation(ExportedType a, ExportedType b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - var ia = a.Implementation; - var ib = b.Implementation; - if (ia == ib) - return true; - if (ia is null || ib is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - ExportedType ea, eb; - FileDef fa, fb; - AssemblyRef aa, ab; - bool checkResolve = true; - - // if one of them is an ExportedType, the other one must be too - 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 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 not null & (ab = ib as AssemblyRef) is not null) - result = Equals(aa, a, ab, b); - else if (fa is not null && ab is not null) - result = Equals(a.DefinitionAssembly, ab, b); - else if (fb is not null && aa is not null) - result = Equals(b.DefinitionAssembly, aa, a); - else { - result = false; - checkResolve = false; - } - if (!result && checkResolve && !DontCheckTypeEquivalence) { - var td1 = a.Resolve(); - var td2 = b.Resolve(); - if (td1 is not null && td2 is not null) - result = TypeDefScopeEquals(td1, td2); - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares resolution scope and implementation - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - bool EqualsScope(TypeRef a, ExportedType b) { - if ((object)a == (object)b) - return true; // both are 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 is null || ib is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - TypeRef ea; - ExportedType eb; - IModule ma; - FileDef fb; - AssemblyRef aa, ab; - bool checkResolve = true; - - // If one is a nested type, the other one must be too - 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 not null & (fb = ib as FileDef) is not null) - result = Equals(a, ma, b, fb); - 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 not null && ab is not null) - result = Equals(a.DefinitionAssembly, ab, b); - else if (fb is not null && aa is not null) - result = Equals(b.DefinitionAssembly, aa, a); - else { - checkResolve = false; - result = false; - } - if (!result && checkResolve && !DontCheckTypeEquivalence) { - var td1 = a.Resolve(); - var td2 = b.Resolve(); - if (td1 is not null && td2 is not null) - result = TypeDefScopeEquals(td1, td2); - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares files - /// - /// File #1 - /// File #2 - /// true if same, false otherwise - bool Equals(FileDef a, FileDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - - return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); - } - - /// - /// Compares a module with a file - /// - /// Module - /// File - /// true if same, false otherwise - bool Equals(IModule a, FileDef b) { - if ((object)a == (object)b) - return true; // both are 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! - return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); - } - - /// - /// Compares modules - /// - /// Module #1 - /// Module #2 - /// true if same, false otherwise - internal bool Equals(IModule a, IModule b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - - return UTF8String.CaseInsensitiveEquals(a.Name, b.Name); - } - - 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 not null && mod.IsManifestModule && mod.Assembly.IsCorLib(); - } - - 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; - - /// - /// Compares modules - /// - /// Module #1 - /// Module #2 - /// true if same, false otherwise - bool Equals(ModuleDef a, ModuleDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals((IModule)a, (IModule)b) && Equals(a.Assembly, b.Assembly); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares assemblies - /// - /// Assembly #1 - /// Assembly #2 - /// true if same, false otherwise - bool Equals(IAssembly a, IAssembly b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - if (!recursionCounter.Increment()) - return false; - - bool result = UTF8String.CaseInsensitiveEquals(a.Name, b.Name) && - (!CompareAssemblyPublicKeyToken || PublicKeyBase.TokenEquals(a.PublicKeyOrToken, b.PublicKeyOrToken)) && - (!CompareAssemblyVersion || Utils.Equals(a.Version, b.Version)) && - (!CompareAssemblyLocale || Utils.LocaleEquals(a.Culture, b.Culture)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, TypeSig b) { - if (IgnoreModifiers) { - a = a.RemoveModifiers(); - b = b.RemoveModifiers(); - } - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (!DontProjectWinMDRefs) { - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - } - - if (a.ElementType != b.ElementType) { - // Signatures must be identical. It's possible to have a U4 in a sig (short form - // of System.UInt32), or a ValueType + System.UInt32 TypeRef (long form), but these - // should not match in a sig (also the long form is invalid). - result = false; - } - else { - switch (a.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.Sentinel: - result = true; - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.SZArray: - case ElementType.Pinned: - result = Equals(a.Next, b.Next); - break; - - case ElementType.Array: - ArraySig ara = a as ArraySig, arb = b as ArraySig; - result = ara.Rank == arb.Rank && - (IgnoreMultiDimensionalArrayLowerBoundsAndSizes || - (Equals(ara.Sizes, arb.Sizes) && - Equals(ara.LowerBounds, arb.LowerBounds))) && - Equals(a.Next, b.Next); - break; - - case ElementType.ValueType: - case ElementType.Class: - if (RawSignatureCompare) - result = TokenEquals((a as ClassOrValueTypeSig).TypeDefOrRef, (b as ClassOrValueTypeSig).TypeDefOrRef); - else - result = Equals((IType)(a as ClassOrValueTypeSig).TypeDefOrRef, (IType)(b as ClassOrValueTypeSig).TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - result = (a as GenericSig).Number == (b as GenericSig).Number; - break; - - case ElementType.GenericInst: - var gia = (GenericInstSig)a; - var gib = (GenericInstSig)b; - if (RawSignatureCompare) { - var gt1 = gia.GenericType; - var gt2 = gib.GenericType; - result = TokenEquals(gt1?.TypeDefOrRef, gt2?.TypeDefOrRef) && - Equals(gia.GenericArguments, gib.GenericArguments); - } - else { - result = Equals(gia.GenericType, gib.GenericType) && - Equals(gia.GenericArguments, gib.GenericArguments); - } - break; - - case ElementType.FnPtr: - result = Equals((a as FnPtrSig).Signature, (b as FnPtrSig).Signature); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - if (RawSignatureCompare) - result = TokenEquals((a as ModifierSig).Modifier, (b as ModifierSig).Modifier) && - Equals(a.Next, b.Next); - else - result = Equals((IType)(a as ModifierSig).Modifier, (IType)(b as ModifierSig).Modifier) && - Equals(a.Next, b.Next); - break; - - case ElementType.ValueArray: - result = (a as ValueArraySig).Size == (b as ValueArraySig).Size && Equals(a.Next, b.Next); - break; - - case ElementType.Module: - result = (a as ModuleSig).Index == (b as ModuleSig).Index && Equals(a.Next, b.Next); - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = false; - break; - } - } - - recursionCounter.Decrement(); - return result; - } - - static bool TokenEquals(ITypeDefOrRef a, ITypeDefOrRef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - return a.MDToken == b.MDToken; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(TypeSig a) => GetHashCode(a, true); - - int GetHashCode(TypeSig a, bool substituteGenericParameters) { - // ******************************************** - // IMPORTANT: This must match GetHashCode(Type) - // ******************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - if (substituteGenericParameters && genericArguments is not null) { - var t = a; - a = genericArguments.Resolve(a); - substituteGenericParameters = t == a; - } - - switch (a.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - // When comparing an ExportedType/TypeDef/TypeRef to a TypeDefOrRefSig/Class/ValueType, - // the ET is ignored, so we must ignore it when calculating the hash. - hash = GetHashCode((IType)(a as TypeDefOrRefSig).TypeDefOrRef); - break; - - case ElementType.Sentinel: - hash = HASHCODE_MAGIC_ET_SENTINEL; - break; - - case ElementType.Ptr: - hash = HASHCODE_MAGIC_ET_PTR + GetHashCode(a.Next, substituteGenericParameters); - break; - - case ElementType.ByRef: - hash = HASHCODE_MAGIC_ET_BYREF + GetHashCode(a.Next, substituteGenericParameters); - break; - - case ElementType.SZArray: - hash = HASHCODE_MAGIC_ET_SZARRAY + GetHashCode(a.Next, substituteGenericParameters); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - 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, 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, substituteGenericParameters); - break; - - case ElementType.Var: - hash = HASHCODE_MAGIC_ET_VAR + (int)(a as GenericVar).Number; - break; - - case ElementType.MVar: - hash = HASHCODE_MAGIC_ET_MVAR + (int)(a as GenericMVar).Number; - break; - - case ElementType.GenericInst: - var gia = (GenericInstSig)a; - hash = HASHCODE_MAGIC_ET_GENERICINST; - hash += GetHashCode(gia.GenericType, substituteGenericParameters); - hash += GetHashCode(gia.GenericArguments, substituteGenericParameters); - break; - - case ElementType.FnPtr: - hash = GetHashCode_FnPtr_SystemIntPtr(); - break; - - case ElementType.ValueArray: - 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, substituteGenericParameters); - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - hash = 0; - break; - } - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares type lists - /// - /// Type list #1 - /// Type list #2 - /// true if same, false otherwise - public bool Equals(IList a, IList b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (a.Count != b.Count) - result = false; - else { - int i; - for (i = 0; i < a.Count; i++) { - if (!Equals(a[i], b[i])) - break; - } - result = i == a.Count; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type list - /// - /// The type list - /// The hash code - public int GetHashCode(IList a) => GetHashCode(a, true); - - int GetHashCode(IList a, bool substituteGenericParameters) { - //************************************************************************ - // IMPORTANT: This code must match any other GetHashCode(IList) - //************************************************************************ - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - uint hash = 0; - for (int i = 0; i < a.Count; i++) { - hash += (uint)GetHashCode(a[i], substituteGenericParameters); - hash = (hash << 13) | (hash >> 19); - } - recursionCounter.Decrement(); - return (int)hash; - } - - bool Equals(IList a, IList b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (a.Count != b.Count) - return false; - for (int i = 0; i < a.Count; i++) { - if (a[i] != b[i]) - return false; - } - return true; - } - - bool Equals(IList a, IList b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (a.Count != b.Count) - return false; - for (int i = 0; i < a.Count; i++) { - if (a[i] != b[i]) - return false; - } - return true; - } - - /// - /// Compares signatures - /// - /// Sig #1 - /// Sig #2 - /// true if same, false otherwise - public bool Equals(CallingConventionSig a, CallingConventionSig b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (a.GetCallingConvention() != b.GetCallingConvention()) - result = false; - else { - switch (a.GetCallingConvention() & CallingConvention.Mask) { - case CallingConvention.Default: - case CallingConvention.C: - case CallingConvention.StdCall: - case CallingConvention.ThisCall: - case CallingConvention.FastCall: - case CallingConvention.VarArg: - case CallingConvention.Property: - case CallingConvention.NativeVarArg: - case CallingConvention.Unmanaged: - MethodBaseSig ma = a as MethodBaseSig, mb = b as MethodBaseSig; - 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 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 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 not null && gb is not null && Equals(ga, gb); - break; - - default: - result = false; - break; - } - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a sig - /// - /// The sig - /// The hash code - public int GetHashCode(CallingConventionSig a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - switch (a.GetCallingConvention() & CallingConvention.Mask) { - case CallingConvention.Default: - case CallingConvention.C: - case CallingConvention.StdCall: - case CallingConvention.ThisCall: - case CallingConvention.FastCall: - 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; - - case CallingConvention.Field: - var fa = a as FieldSig; - hash = fa is null ? 0 : GetHashCode(fa); - break; - - case CallingConvention.LocalSig: - var la = a as LocalSig; - hash = la is null ? 0 : GetHashCode(la); - break; - - case CallingConvention.GenericInst: - var ga = a as GenericInstMethodSig; - hash = ga is null ? 0 : GetHashCode(ga); - break; - - default: - hash = GetHashCode_CallingConvention(a); - break; - } - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares method/property sigs - /// - /// Method/property #1 - /// Method/property #2 - /// true if same, false otherwise - public bool Equals(MethodBaseSig a, MethodBaseSig b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = a.GetCallingConvention() == b.GetCallingConvention() && - (DontCompareReturnType || Equals(a.RetType, b.RetType)) && - Equals(a.Params, b.Params) && - (!a.Generic || a.GenParamCount == b.GenParamCount) && - (!CompareSentinelParams || Equals(a.ParamsAfterSentinel, b.ParamsAfterSentinel)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a method/property sig - /// - /// The method/property sig - /// The hash code - public int GetHashCode(MethodBaseSig a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - hash = GetHashCode_CallingConvention(a) + - GetHashCode(a.Params); - if (!DontCompareReturnType) - hash += GetHashCode(a.RetType); - if (a.Generic) - hash += GetHashCode_ElementType_MVar((int)a.GenParamCount); - if (CompareSentinelParams) - hash += GetHashCode(a.ParamsAfterSentinel); - - recursionCounter.Decrement(); - return hash; - } - - int GetHashCode_CallingConvention(CallingConventionSig a) => GetHashCode(a.GetCallingConvention()); - - int GetHashCode(CallingConvention a) { - //******************************************************************* - // IMPORTANT: This hash must match the Reflection call conv hash code - //******************************************************************* - - switch (a & CallingConvention.Mask) { - case CallingConvention.Default: - case CallingConvention.C: - case CallingConvention.StdCall: - case CallingConvention.ThisCall: - case CallingConvention.FastCall: - case CallingConvention.VarArg: - case CallingConvention.Property: - case CallingConvention.GenericInst: - case CallingConvention.Unmanaged: - case CallingConvention.NativeVarArg: - case CallingConvention.Field: - return (int)(a & (CallingConvention.Generic | CallingConvention.HasThis | CallingConvention.ExplicitThis)); - - case CallingConvention.LocalSig: - default: - return (int)a; - } - } - - /// - /// Compares field sigs - /// - /// Field sig #1 - /// Field sig #2 - /// true if same, false otherwise - public bool Equals(FieldSig a, FieldSig b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = a.GetCallingConvention() == b.GetCallingConvention() && Equals(a.Type, b.Type); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a field sig - /// - /// The field sig - /// The hash code - public int GetHashCode(FieldSig a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - hash = GetHashCode_CallingConvention(a) + GetHashCode(a.Type); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares local sigs - /// - /// Local sig #1 - /// Local sig #2 - /// true if same, false otherwise - public bool Equals(LocalSig a, LocalSig b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = a.GetCallingConvention() == b.GetCallingConvention() && Equals(a.Locals, b.Locals); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a local sig - /// - /// The local sig - /// The hash code - public int GetHashCode(LocalSig a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - hash = GetHashCode_CallingConvention(a) + GetHashCode(a.Locals); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares generic method instance sigs - /// - /// Generic inst method #1 - /// Generic inst method #2 - /// true if same, false otherwise - public bool Equals(GenericInstMethodSig a, GenericInstMethodSig b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = a.GetCallingConvention() == b.GetCallingConvention() && Equals(a.GenericArguments, b.GenericArguments); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a generic instance method sig - /// - /// The generic inst method sig - /// The hash code - public int GetHashCode(GenericInstMethodSig a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - int hash; - - hash = GetHashCode_CallingConvention(a) + GetHashCode(a.GenericArguments); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(IMethod a, IMethod b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - MethodDef mda, mdb; - MemberRef mra, mrb; - MethodSpec msa, msb; - - 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 not null & (mrb = b as MemberRef) is not null) - result = Equals(mra, mrb); - else if ((msa = a as MethodSpec) is not null && (msb = b as MethodSpec) is not null) - result = Equals(msa, msb); - else if (mda is not null && mrb is not null) - result = Equals(mda, mrb); - else if (mra is not null && mdb is not null) - result = Equals(mdb, mra); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a method - /// - /// The method - /// The hash code - public int GetHashCode(IMethod a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash; - MethodDef mda; - MemberRef mra; - MethodSpec msa; - - if ((mda = a as MethodDef) is not null) - hash = GetHashCode(mda); - else if ((mra = a as MemberRef) is not null) - hash = GetHashCode(mra); - else if ((msa = a as MethodSpec) is not null) - hash = GetHashCode(msa); - else - hash = 0; - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MemberRef a, MethodDef b) => Equals(b, a); - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodDef a, MemberRef b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - if (!DontProjectWinMDRefs) { - var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - if (mra is not null) { - result = Equals(mra, b); - goto exit; - } - } - result = (PrivateScopeMethodIsComparable || !a.IsPrivateScope) && - Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.Signature, b.Signature) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.Class)); - -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodDef a, MethodDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - if (!DontProjectWinMDRefs) { - var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - var mrb = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b); - if (mra is not null || mrb is not null) { - result = Equals((IMethod)mra ?? a, (IMethod)mrb ?? b); - goto exit; - } - } - result = Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.Signature, b.Signature) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a method - /// - /// The method - /// The hash code - public int GetHashCode(MethodDef a) { - // *********************************************************************** - // IMPORTANT: This hash code must match the MemberRef/MethodBase hash code - // *********************************************************************** - if (a is null) - return 0; - if (!DontProjectWinMDRefs) { - var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (mra is not null) - return GetHashCode(mra); - } - - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_MethodFieldName(a.Name) + - GetHashCode(a.Signature); - if (CompareMethodFieldDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares MemberRefs - /// - /// MemberRef #1 - /// MemberRef #2 - /// true if same, false otherwise - public bool Equals(MemberRef a, MemberRef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - if (!DontProjectWinMDRefs) { - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - b = WinMDHelpers.ToCLR(b.Module ?? sourceModule, b) ?? b; - } - bool result = Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.Signature, b.Signature) && - (!CompareMethodFieldDeclaringType || Equals(a.Class, b.Class)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a MemberRef - /// - /// The MemberRef - /// The hash code - public int GetHashCode(MemberRef a) { - // ******************************************************************************** - // IMPORTANT: This hash code must match the MethodDef/FieldDef/MethodBase hash code - // ******************************************************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - - int hash = GetHashCode_MethodFieldName(a.Name); - GenericInstSig git; - if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { - InitializeGenericArguments(); - genericArguments.PushTypeArgs(git.GenericArguments); - hash += GetHashCode(a.Signature); - genericArguments.PopTypeArgs(); - } - else - hash += GetHashCode(a.Signature); - if (CompareMethodFieldDeclaringType) - hash += GetHashCode(a.Class); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares MethodSpecs - /// - /// MethodSpec #1 - /// MethodSpec #2 - /// true if same, false otherwise - public bool Equals(MethodSpec a, MethodSpec b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals(a.Method, b.Method) && Equals(a.Instantiation, b.Instantiation); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a MethodSpec - /// - /// The MethodSpec - /// The hash code - public int GetHashCode(MethodSpec a) { - // ************************************************************* - // IMPORTANT: This hash code must match the MethodBase hash code - // ************************************************************* - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - var gim = a.GenericInstMethodSig; - if (gim is not null) { - InitializeGenericArguments(); - genericArguments.PushMethodArgs(gim.GenericArguments); - } - int hash = GetHashCode(a.Method); - if (gim is not null) - genericArguments.PopMethodArgs(); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares MemberRefParents - /// - /// MemberRefParent #1 - /// MemberRefParent #2 - /// true if same, false otherwise - bool Equals(IMemberRefParent a, IMemberRefParent b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - ITypeDefOrRef ita, itb; - ModuleRef moda, modb; - MethodDef ma, mb; - TypeDef td; - - 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 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 not null && (mb = b as MethodDef) is not null) - result = Equals(ma, mb); - else if (modb is not null && (td = a as TypeDef) is not null) - result = EqualsGlobal(td, modb); - else if (moda is not null && (td = b as TypeDef) is not null) - result = EqualsGlobal(td, moda); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a MemberRefParent - /// - /// The MemberRefParent - /// The hash code - int GetHashCode(IMemberRefParent a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash; - ITypeDefOrRef ita; - MethodDef ma; - - 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 not null) { - // Only use the declaring type so we get the same hash code when hashing a MethodBase. - hash = GetHashCode(ma.DeclaringType); - } - else - hash = 0; - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(IField a, IField b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - FieldDef fa, fb; - MemberRef ma, mb; - - 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 not null & (mb = b as MemberRef) is not null) - result = Equals(ma, mb); - else if (fa is not null && mb is not null) - result = Equals(fa, mb); - else if (fb is not null && ma is not null) - result = Equals(fb, ma); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a field - /// - /// The field - /// The hash code - public int GetHashCode(IField a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash; - FieldDef fa; - MemberRef ma; - - if ((fa = a as FieldDef) is not null) - hash = GetHashCode(fa); - else if ((ma = a as MemberRef) is not null) - hash = GetHashCode(ma); - else - hash = 0; - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(MemberRef a, FieldDef b) => Equals(b, a); - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldDef a, MemberRef b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = (PrivateScopeFieldIsComparable || !a.IsPrivateScope) && - Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.Signature, b.Signature) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.Class)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldDef a, FieldDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.Signature, b.Signature) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a field - /// - /// The field - /// The hash code - public int GetHashCode(FieldDef a) { - // ********************************************************************** - // IMPORTANT: This hash code must match the MemberRef/FieldInfo hash code - // ********************************************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_MethodFieldName(a.Name) + - GetHashCode(a.Signature); - if (CompareMethodFieldDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares properties - /// - /// Property #1 - /// Property #2 - /// true if same, false otherwise - public bool Equals(PropertyDef a, PropertyDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_PropertyNames(a.Name, b.Name) && - Equals(a.Type, b.Type) && - (!ComparePropertyDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a property - /// - /// The property - /// The hash code - public int GetHashCode(PropertyDef a) { - // *************************************************************** - // IMPORTANT: This hash code must match the PropertyInfo hash code - // *************************************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - var sig = a.PropertySig; - int hash = GetHashCode_PropertyName(a.Name) + - GetHashCode(sig?.RetType); - if (ComparePropertyDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares events - /// - /// Event #1 - /// Event #2 - /// true if same, false otherwise - public bool Equals(EventDef a, EventDef b) { - if (a == b) - return true; - if (a is null || b is null) - return false; - if (ReferenceCompareForMemberDefsInSameModule && InSameModule(a, b)) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_EventNames(a.Name, b.Name) && - Equals((IType)a.EventType, (IType)b.EventType) && - (!CompareEventDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of an event - /// - /// The event - /// The hash code - public int GetHashCode(EventDef a) { - // ************************************************************ - // IMPORTANT: This hash code must match the EventInfo hash code - // ************************************************************ - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_EventName(a.Name) + - GetHashCode((IType)a.EventType); - if (CompareEventDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - // Compares a with b, and a must be the global type - bool EqualsGlobal(TypeDef a, ModuleRef b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = a.IsGlobalModuleType && - Equals((IModule)a.Module, (IModule)b) && - Equals(a.DefinitionAssembly, GetAssembly(b.Module)); - - recursionCounter.Decrement(); - return result; - } - - static AssemblyDef GetAssembly(ModuleDef module) => module?.Assembly; - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, IType b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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 is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - TypeDef td; - TypeRef tr; - TypeSpec ts; - TypeSig sig; - ExportedType et; - - if ((td = a as TypeDef) is not null) - result = Equals(td, b); - else if ((tr = a as TypeRef) is not null) - result = Equals(tr, b); - else if ((ts = a as TypeSpec) is not null) - result = Equals(ts, b); - else if ((sig = a as TypeSig) is not null) - result = Equals(sig, b); - else if ((et = a as ExportedType) is not null) - result = Equals(et, b); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, TypeDef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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 is null) - return false; - if (b is null) - return a.IsGlobalModuleType; - if (!recursionCounter.Increment()) - return false; - - bool result; - - if (!DontProjectWinMDRefs) { - var tra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (tra is not null) { - result = Equals(tra, b); - goto exit; - } - } - result = !b.HasElementType && - Equals_TypeNames(a.Name, ReflectionExtensions.Unescape(b.Name)) && - Equals_TypeNamespaces(a.Namespace, b) && - EnclosingTypeEquals(a.DeclaringType, b.DeclaringType) && - (DontCompareTypeScope || Equals(a.Module, b.Module)); - -exit: ; - recursionCounter.Decrement(); - return result; - } - - bool EnclosingTypeEquals(TypeDef a, Type b) { - // b is null doesn't mean that b is the global type - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a, b); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, TypeRef b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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 is null) - return false; - 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; - TypeRef dta; - IModule aMod; - AssemblyRef aAsm; - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - - var scope = a.ResolutionScope; - - if (!b.IsTypeDef()) - 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 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 not null) // 'a' is defined in the same assembly as 'b' - result = Equals(b, aMod, a); - else if ((aAsm = scope as AssemblyRef) is not null) - result = Equals(b.Assembly, aAsm, a); - else { - result = false; - //TODO: Handle the case where scope is null - } - - recursionCounter.Decrement(); - return result; - } - - bool Equals_TypeNamespaces(UTF8String a, Type b) { - if (b.IsNested) - return true; - return Equals_TypeNamespaces(a, b.Namespace); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, TypeSpec b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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 is null) - return false; - if (b is null) - return false; // Must use a ModuleRef to reference the global type, so always fail - return Equals(a.TypeSig, b); - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, TypeSig b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(TypeSig a, Type b) => Equals(a, b, null, false); - - bool Equals(ITypeDefOrRef a, Type b, Type declaringType) { - if (a is TypeSpec ts) - return Equals(ts.TypeSig, b, declaringType); - return Equals(a, b); - } - - /// - /// Checks whether it's FnPtr&, FnPtr*, FnPtr[], or FnPtr[...] - /// - /// The type - static bool IsFnPtrElementType(Type a) { - if (a is null || !a.HasElementType) - return false; - var et = a.GetElementType(); - if (et is null || et.HasElementType) - return false; - if (et != typeof(IntPtr)) // FnPtr is mapped to System.IntPtr - return false; - if (!a.FullName.StartsWith("(fnptr)")) - return false; - - return true; - } - - /// - /// Compares types - /// - /// 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, 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) - return false; - 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; - - bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(b); - if (genericArguments is not null) - a = genericArguments.Resolve(a); - - switch (a.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - result = Equals(((TypeDefOrRefSig)a).TypeDefOrRef, b, declaringType); - break; - - case ElementType.Ptr: - if (!b.IsPointer) - result = false; - else if (IsFnPtrElementType(b)) { - a = a.Next.RemoveModifiers(); - result = a is not null && a.ElementType == ElementType.FnPtr; - } - else - result = Equals(a.Next, b.GetElementType(), declaringType); - break; - - case ElementType.ByRef: - if (!b.IsByRef) - result = false; - else if (IsFnPtrElementType(b)) { - a = a.Next.RemoveModifiers(); - result = a is not null && a.ElementType == ElementType.FnPtr; - } - else - result = Equals(a.Next, b.GetElementType(), declaringType); - break; - - case ElementType.SZArray: - if (!b.IsArray || !b.IsSZArray()) - result = false; - else if (IsFnPtrElementType(b)) { - a = a.Next.RemoveModifiers(); - result = a is not null && a.ElementType == ElementType.FnPtr; - } - else - result = Equals(a.Next, b.GetElementType(), declaringType); - break; - - case ElementType.Pinned: - result = Equals(a.Next, b, declaringType); - break; - - case ElementType.Array: - if (!b.IsArray || b.IsSZArray()) - result = false; - else { - var ara = a as ArraySig; - result = ara.Rank == b.GetArrayRank() && - (IsFnPtrElementType(b) ? - (a = a.Next.RemoveModifiers()) is not null && a.ElementType == ElementType.FnPtr : - Equals(a.Next, b.GetElementType(), declaringType)); - } - break; - - case ElementType.ValueType: - case ElementType.Class: - result = Equals((a as ClassOrValueTypeSig).TypeDefOrRef, b, declaringType); - break; - - case ElementType.Var: - result = b.IsGenericParameter && - b.GenericParameterPosition == (a as GenericSig).Number && - b.DeclaringMethod is null; - break; - - case ElementType.MVar: - result = b.IsGenericParameter && - b.GenericParameterPosition == (a as GenericSig).Number && - b.DeclaringMethod is not null; - break; - - case ElementType.GenericInst: - if (!(b.IsGenericType && !b.IsGenericTypeDefinition) && !treatAsGenericInst2) { - result = false; - break; - } - var gia = (GenericInstSig)a; - 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, declaringType); - break; - - case ElementType.FnPtr: - // At least in method sigs, this will be mapped to System.IntPtr - result = b == typeof(IntPtr); - break; - - case ElementType.Sentinel: - case ElementType.ValueArray: - case ElementType.Module: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - result = false; - break; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - public bool Equals(Type a, ExportedType b) => Equals(b, a); - - /// - /// Compares types - /// - /// Type #1 - /// Type #2 - /// true if same, false otherwise - 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 is null) - return false; - 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; - ExportedType dta; - FileDef aFile; - AssemblyRef aAsm; - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - - var scope = a.Implementation; - - if (!b.IsTypeDef()) - 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 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 not null) - result = Equals(b, aFile, a); - else if ((aAsm = scope as AssemblyRef) is not null) - result = Equals(b.Assembly, aAsm, a); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a type - /// - /// The type - /// The hash code - public int GetHashCode(Type a) => GetHashCode(a, false); - - /// - /// Gets the hash code of a type - /// - /// The type - /// true if we should treat - /// as a generic instance type - /// The hash code - 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 - // ************************************************************************** - if (a is null) // Could be global type - return GetHashCode_TypeDef(a); - if (!recursionCounter.Increment()) - return 0; - int hash; - - bool treatAsGenericInst2 = treatAsGenericInst ?? declaringType.MustTreatTypeAsGenericInstType(a); - switch (treatAsGenericInst2 ? ElementType.GenericInst : a.GetElementType2()) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.ValueType: - case ElementType.Class: - hash = GetHashCode_TypeDef(a); - break; - - case ElementType.FnPtr: - hash = GetHashCode_FnPtr_SystemIntPtr(); - break; - - case ElementType.Sentinel: - hash = HASHCODE_MAGIC_ET_SENTINEL; - break; - - case ElementType.Ptr: - hash = HASHCODE_MAGIC_ET_PTR + - (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(), declaringType)); - break; - - case ElementType.SZArray: - hash = HASHCODE_MAGIC_ET_SZARRAY + - (IsFnPtrElementType(a) ? GetHashCode_FnPtr_SystemIntPtr() : GetHashCode(a.GetElementType(), declaringType)); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Pinned: - 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(), declaringType)); - break; - - case ElementType.Var: - hash = HASHCODE_MAGIC_ET_VAR + a.GenericParameterPosition; - break; - - case ElementType.MVar: - hash = HASHCODE_MAGIC_ET_MVAR + a.GenericParameterPosition; - break; - - case ElementType.GenericInst: - hash = HASHCODE_MAGIC_ET_GENERICINST + GetHashCode(a.GetGenericTypeDefinition(), false) + - GetHashCode(a.GetGenericArguments(), declaringType); - break; - - case ElementType.ValueArray: - case ElementType.Module: - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - hash = 0; - break; - } - - recursionCounter.Decrement(); - return hash; - } - - /// - /// 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, Type declaringType) { - //************************************************************************ - // IMPORTANT: This code must match any other GetHashCode(IList) - //************************************************************************ - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - uint hash = 0; - for (int i = 0; i < a.Count; i++) { - hash += (uint)GetHashCode(a[i], declaringType); - hash = (hash << 13) | (hash >> 19); - } - recursionCounter.Decrement(); - return (int)hash; - } - - /// - /// Gets the hash code of a list with only generic method parameters () - /// - /// Number of generic method parameters - /// Hash code - static int GetHashCode_ElementType_MVar(int numGenericParams) => GetHashCode(numGenericParams, HASHCODE_MAGIC_ET_MVAR); - - static int GetHashCode(int numGenericParams, int etypeHashCode) { - //************************************************************************ - // IMPORTANT: This code must match any other GetHashCode(IList) - //************************************************************************ - uint hash = 0; - for (int i = 0; i < numGenericParams; i++) { - hash += (uint)(etypeHashCode + i); - hash = (hash << 13) | (hash >> 19); - } - return (int)hash; - } - - /// - /// Gets the hash code of a TypeDef type - /// - /// The type - /// The hash code - public int GetHashCode_TypeDef(Type a) { - // ************************************************************************************ - // IMPORTANT: This hash code must match the Type/TypeRef/TypeDef/ExportedType - // hash code and GetHashCode_FnPtr_SystemIntPtr() method - // ************************************************************************************ - - // A global method/field's declaring type is null. This is the reason we must - // return GetHashCodeGlobalType() here. - if (a is null) - return GetHashCodeGlobalType(); - int hash; - hash = GetHashCode_TypeName(ReflectionExtensions.Unescape(a.Name)); - if (a.IsNested) - hash += HASHCODE_MAGIC_NESTED_TYPE; - else - hash += GetHashCode_TypeNamespace(a.Namespace); - return hash; - } - - /// - /// Compares type lists - /// - /// 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, Type declaringType) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (a.Count != b.Count) - result = false; - else { - int i; - for (i = 0; i < a.Count; i++) { - if (!Equals(a[i], b[i], declaringType)) - break; - } - result = i == a.Count; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares modules - /// - /// Module #1 - /// Module #2 - /// true if same, false otherwise - bool Equals(ModuleDef a, Module b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals((IModule)a, b) && Equals(a.Assembly, b.Assembly); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares a file and a module - /// - /// File - /// Module - /// true if same, false otherwise - bool Equals(FileDef a, Module b) { - if ((object)a == (object)b) - return true; // both are 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 - return UTF8String.ToSystemStringOrEmpty(a.Name).Equals(b.Name, StringComparison.OrdinalIgnoreCase); - } - - /// - /// Compares modules - /// - /// Module #1 - /// Module #2 - /// true if same, false otherwise - bool Equals(IModule a, Module b) { - if ((object)a == b) - return true; - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - - // Use b.ScopeName and not b.Name since b.Name is just the file name w/o path - return UTF8String.ToSystemStringOrEmpty(a.Name).Equals(b.ScopeName, StringComparison.OrdinalIgnoreCase); - } - - /// - /// Compares assemblies - /// - /// Assembly #1 - /// Assembly #2 - /// true if same, false otherwise - bool Equals(IAssembly a, Assembly b) { - if ((object)a == b) - return true; - if (a is null || b is null) - return false; - if (!MscorlibIsNotSpecial && IsCorLib(a) && IsCorLib(b)) - return true; - if (!recursionCounter.Increment()) - return false; - - var bAsmName = b.GetName(); - bool result = UTF8String.ToSystemStringOrEmpty(a.Name).Equals(bAsmName.Name, StringComparison.OrdinalIgnoreCase) && - (!CompareAssemblyPublicKeyToken || PublicKeyBase.TokenEquals(a.PublicKeyOrToken, new PublicKeyToken(bAsmName.GetPublicKeyToken()))) && - (!CompareAssemblyVersion || Utils.Equals(a.Version, bAsmName.Version)) && - (!CompareAssemblyLocale || Utils.LocaleEquals(a.Culture, bAsmName.CultureInfo.Name)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares method declaring types - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - bool DeclaringTypeEquals(IMethod a, MethodBase b) { - // If this is disabled, always return true, even if one is null, etc. - if (!CompareMethodFieldDeclaringType) - return true; - - if ((object)a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - MethodDef md; - MemberRef mr; - MethodSpec ms; - - if ((md = a as MethodDef) is not null) - result = DeclaringTypeEquals(md, b); - else if ((mr = a as MemberRef) is not null) - result = DeclaringTypeEquals(mr, b); - else if ((ms = a as MethodSpec) is not null) - result = DeclaringTypeEquals(ms, b); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - bool DeclaringTypeEquals(MethodDef a, MethodBase b) { - // If this is disabled, always return true, even if one is null, etc. - if (!CompareMethodFieldDeclaringType) - return true; - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a.DeclaringType, b.DeclaringType); - } - - bool DeclaringTypeEquals(MemberRef a, MethodBase b) { - // If this is disabled, always return true, even if one is null, etc. - if (!CompareMethodFieldDeclaringType) - return true; - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return Equals(a.Class, b.DeclaringType, b.Module); - } - - bool DeclaringTypeEquals(MethodSpec a, MethodBase b) { - // If this is disabled, always return true, even if one is null, etc. - if (!CompareMethodFieldDeclaringType) - return true; - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - return DeclaringTypeEquals(a.Method, b); - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodBase a, IMethod b) => Equals(b, a); - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(IMethod a, MethodBase b) { - if ((object)a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - MethodDef md; - MemberRef mr; - MethodSpec ms; - - if ((md = a as MethodDef) is not null) - result = Equals(md, b); - else if ((mr = a as MemberRef) is not null) - result = Equals(mr, b); - else if ((ms = a as MethodSpec) is not null) - result = Equals(ms, b); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodBase a, MethodDef b) => Equals(b, a); - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodDef a, MethodBase b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - if (!DontProjectWinMDRefs) { - var mra = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a); - if (mra is not null) { - result = Equals(mra, b); - goto exit; - } - } - - var amSig = a.MethodSig; - result = Equals_MethodFieldNames(a.Name, b.Name) && - amSig is not null && - ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || - (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)) && - Equals(amSig, b) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - -exit: ; - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares method sigs - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodBase a, MethodSig b) => Equals(b, a); - - /// - /// Compares method sigs - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodSig a, MethodBase b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - 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) && - (!a.Generic || a.GenParamCount == b.GetGenericArguments().Length); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodBase a, MemberRef b) => Equals(b, a); - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MemberRef a, MethodBase b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (!DontProjectWinMDRefs) - a = WinMDHelpers.ToCLR(a.Module ?? sourceModule, a) ?? a; - if (b.IsGenericMethod && !b.IsGenericMethodDefinition) { - // 'a' must be a method ref in a generic type. This comparison must match - // the MethodSpec vs MethodBase comparison code. - 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); - - result = result && GenericMethodArgsEquals((int)a.MethodSig.GenParamCount, b.GetGenericArguments()); - } - else { - var amSig = a.MethodSig; - result = Equals_MethodFieldNames(a.Name, b.Name) && - amSig is not null && - ((amSig.Generic && b.IsGenericMethodDefinition && b.IsGenericMethod) || - (!amSig.Generic && !b.IsGenericMethodDefinition && !b.IsGenericMethod)); - - GenericInstSig git; - if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { - InitializeGenericArguments(); - genericArguments.PushTypeArgs(git.GenericArguments); - result = result && Equals(amSig, b); - genericArguments.PopTypeArgs(); - } - else - result = result && Equals(amSig, b); - - result = result && (!CompareMethodFieldDeclaringType || Equals(a.Class, b.DeclaringType, b.Module)); - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares generic method args, making sure only - /// contains s. - /// - /// Number of generic method args in method #1 - /// Generic method args in method #2 - /// true if same, false otherwise - static bool GenericMethodArgsEquals(int numMethodArgs, IList methodGenArgs) { - if (numMethodArgs != methodGenArgs.Count) - return false; - for (int i = 0; i < numMethodArgs; i++) { - if (methodGenArgs[i].GetElementType2() != ElementType.MVar) - return false; - } - return true; - } - - 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 is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - ITypeDefOrRef ita; - ModuleRef moda; - MethodDef ma; - TypeDef td; - - if ((ita = a as ITypeDefOrRef) is not null) - result = Equals((IType)ita, b); - 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 not null) - result = Equals(ma.DeclaringType, b); - else if (b is null && (td = a as TypeDef) is not null) - result = td.IsGlobalModuleType; - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodBase a, MethodSpec b) => Equals(b, a); - - /// - /// Compares methods - /// - /// Method #1 - /// Method #2 - /// true if same, false otherwise - public bool Equals(MethodSpec a, MethodBase b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - // Make sure it's a MethodSpec - bool result = b.IsGenericMethod && !b.IsGenericMethodDefinition; - - // Don't compare declaring types yet because the resolved method has the wrong - // 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(), b.DeclaringType); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a MethodBase - /// - /// The MethodBase - /// The hash code - public int GetHashCode(MethodBase a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - // *********************************************************************** - // IMPORTANT: This hash code must match the MemberRef/MethodSpec hash code - // *********************************************************************** - int hash = GetHashCode_MethodFieldName(a.Name) + - GetHashCode_MethodSig(a); - if (CompareMethodFieldDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - int GetHashCode_MethodSig(MethodBase a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - 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) - hash += GetHashCode_ReturnType(a); - if (a.IsGenericMethod) - hash += GetHashCode_ElementType_MVar(a.GetGenericArguments().Length); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Gets the hash code of a parameter list - /// - /// The type list - /// Declaring type of method that owns parameter - /// The hash code - int GetHashCode(IList a, Type declaringType) { - //************************************************************************ - // IMPORTANT: This code must match any other GetHashCode(IList) - //************************************************************************ - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - uint hash = 0; - for (int i = 0; i < a.Count; i++) { - hash += (uint)GetHashCode(a[i], declaringType); - hash = (hash << 13) | (hash >> 19); - } - recursionCounter.Decrement(); - return (int)hash; - } - - int GetHashCode_ReturnType(MethodBase a) { - var mi = a as MethodInfo; - if (mi is not null) - return GetHashCode(mi.ReturnParameter, a.DeclaringType); - return GetHashCode(typeof(void)); - } - - int GetHashCode(ParameterInfo a, Type declaringType) => GetHashCode(a.ParameterType, declaringType); - - /// - /// Compares calling conventions - /// - /// Calling convention - /// Method - /// - static bool Equals(CallingConvention a, MethodBase b) { - var bc = b.CallingConvention; - - if (((a & CallingConvention.Generic) != 0) != b.IsGenericMethod) - return false; - if (((a & CallingConvention.HasThis) != 0) != ((bc & CallingConventions.HasThis) != 0)) - return false; - if (((a & CallingConvention.ExplicitThis) != 0) != ((bc & CallingConventions.ExplicitThis) != 0)) - return false; - - var cca = a & CallingConvention.Mask; - switch (bc & CallingConventions.Any) { - case CallingConventions.Standard: - if (cca == CallingConvention.VarArg || cca == CallingConvention.NativeVarArg) - return false; - break; - - case CallingConventions.VarArgs: - if (cca != CallingConvention.VarArg && cca != CallingConvention.NativeVarArg) - return false; - break; - - case CallingConventions.Any: - default: - break; - } - - return true; - } - - static int GetHashCode_CallingConvention(CallingConventions a, bool isGeneric) { - //************************************************************** - // IMPORTANT: This hash must match the other call conv hash code - //************************************************************** - - CallingConvention cc = 0; - - if (isGeneric) - cc |= CallingConvention.Generic; - if ((a & CallingConventions.HasThis) != 0) - cc |= CallingConvention.HasThis; - if ((a & CallingConventions.ExplicitThis) != 0) - cc |= CallingConvention.ExplicitThis; - - return (int)cc; - } - - /// - /// Compares return types - /// - /// Return type #1 - /// MethodBase - /// true if same, false otherwise - bool ReturnTypeEquals(TypeSig a, MethodBase b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - var mi = b as MethodInfo; - if (mi is not null) - result = Equals(a, mi.ReturnParameter, b.DeclaringType); - else if (b is ConstructorInfo) - result = IsSystemVoid(a); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - static bool IsSystemVoid(TypeSig a) => a.RemovePinnedAndModifiers().GetElementType() == ElementType.Void; - - /// - /// Compares parameter lists - /// - /// Type list #1 - /// Type list #2 - /// Declaring type of method that owns parameter - /// true if same, false otherwise - 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) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (a.Count != b.Count) - result = false; - else { - int i; - for (i = 0; i < a.Count; i++) { - if (!Equals(a[i], b[i], declaringType)) - break; - } - result = i == a.Count; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares parameter types - /// - /// Parameter type #1 - /// Parameter #2 - /// Declaring type of method that owns parameter - /// true if same, false otherwise - bool Equals(TypeSig a, ParameterInfo b, Type declaringType) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = ModifiersEquals(a, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && - Equals(a2, b.ParameterType, declaringType); - - recursionCounter.Decrement(); - return result; - } - - bool ModifiersEquals(TypeSig a, IList reqMods2, IList optMods2, out TypeSig aAfterModifiers) { - aAfterModifiers = a; - if (!(a is ModifierSig)) - return reqMods2.Count == 0 && optMods2.Count == 0; - if (!recursionCounter.Increment()) - return false; - bool result; - - var reqMods1 = new List(reqMods2.Count); - var optMods1 = new List(optMods2.Count); - while (true) { - var modifierSig = aAfterModifiers as ModifierSig; - if (modifierSig is null) - break; - if (modifierSig is CModOptSig) - optMods1.Add(modifierSig.Modifier); - else - reqMods1.Add(modifierSig.Modifier); - - // This can only loop forever if the user created a loop. It's not possible - // to create a loop with invalid metadata. - aAfterModifiers = aAfterModifiers.Next; - } - optMods1.Reverse(); - reqMods1.Reverse(); - - result = reqMods1.Count == reqMods2.Count && - optMods1.Count == optMods2.Count && - ModifiersEquals(reqMods1, reqMods2) && - ModifiersEquals(optMods1, optMods2); - - recursionCounter.Decrement(); - return result; - } - - bool ModifiersEquals(IList a, IList b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - bool result; - - if (a.Count != b.Count) - result = false; - else { - int i; - for (i = 0; i < b.Count; i++) { - if (!Equals(a[i], b[i])) - break; - } - result = i == b.Count; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldInfo a, IField b) => Equals(b, a); - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(IField a, FieldInfo b) { - if ((object)a == b) - return true; - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result; - FieldDef fa; - MemberRef ma; - - if ((fa = a as FieldDef) is not null) - result = Equals(fa, b); - else if ((ma = a as MemberRef) is not null) - result = Equals(ma, b); - else - result = false; - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldInfo a, FieldDef b) => Equals(b, a); - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldDef a, FieldInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_MethodFieldNames(a.Name, b.Name) && - Equals(a.FieldSig, b) && - (!CompareMethodFieldDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - bool Equals(FieldSig a, FieldInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - 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); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(FieldInfo a, MemberRef b) => Equals(b, a); - - /// - /// Compares fields - /// - /// Field #1 - /// Field #2 - /// true if same, false otherwise - public bool Equals(MemberRef a, FieldInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_MethodFieldNames(a.Name, b.Name); - - GenericInstSig git; - if (CompareMethodFieldDeclaringType && !DontSubstituteGenericParameters && (git = GetGenericInstanceType(a.Class)) is not null) { - InitializeGenericArguments(); - genericArguments.PushTypeArgs(git.GenericArguments); - result = result && Equals(a.FieldSig, b); - genericArguments.PopTypeArgs(); - } - else - result = result && Equals(a.FieldSig, b); - - result = result && (!CompareMethodFieldDeclaringType || Equals(a.Class, b.DeclaringType, b.Module)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a field - /// - /// The field - /// The hash code - public int GetHashCode(FieldInfo a) { - // ************************************************************ - // IMPORTANT: This hash code must match the MemberRef hash code - // ************************************************************ - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_MethodFieldName(a.Name) + - GetHashCode_FieldSig(a); - if (CompareMethodFieldDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - int GetHashCode_FieldSig(FieldInfo a) { - if (a is null) - return 0; - if (!recursionCounter.Increment()) - 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(); - return hash; - } - - /// - /// Compares properties - /// - /// Property #1 - /// Property #2 - /// true if same, false otherwise - public bool Equals(PropertyDef a, PropertyInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_PropertyNames(a.Name, b.Name) && - Equals(a.PropertySig, b) && - (!ComparePropertyDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - bool Equals(PropertySig a, PropertyInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = ModifiersEquals(a.RetType, b.GetRequiredCustomModifiers(), b.GetOptionalCustomModifiers(), out var a2) && - Equals(a2, b.PropertyType, b.DeclaringType); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of a property - /// - /// The property - /// The hash code - public int GetHashCode(PropertyInfo a) { - // ************************************************************** - // IMPORTANT: This hash code must match the PropertyDef hash code - // ************************************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_PropertyName(a.Name) + - GetHashCode(a.PropertyType, a.DeclaringType); - if (ComparePropertyDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - /// - /// Compares events - /// - /// Event #1 - /// Event #2 - /// true if same, false otherwise - public bool Equals(EventDef a, EventInfo b) { - if ((object)a == (object)b) - return true; // both are null - if (a is null || b is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool result = Equals_EventNames(a.Name, b.Name) && - Equals(a.EventType, b.EventHandlerType, b.DeclaringType) && - (!CompareEventDeclaringType || Equals(a.DeclaringType, b.DeclaringType)); - - recursionCounter.Decrement(); - return result; - } - - /// - /// Gets the hash code of an event - /// - /// The event - /// The hash code - public int GetHashCode(EventInfo a) { - // *********************************************************** - // IMPORTANT: This hash code must match the EventDef hash code - // *********************************************************** - if (a is null) - return 0; - if (!recursionCounter.Increment()) - return 0; - - int hash = GetHashCode_EventName(a.Name) + - GetHashCode(a.EventHandlerType, a.DeclaringType); - if (CompareEventDeclaringType) - hash += GetHashCode(a.DeclaringType); - - recursionCounter.Decrement(); - return hash; - } - - /// - public override string ToString() => $"{recursionCounter} - {options}"; - - static bool InSameModule(IOwnerModule a, IOwnerModule b) => a.Module is { } module && module == b.Module; - } -} diff --git a/Plugins/dnlib/DotNet/SignatureReader.cs b/Plugins/dnlib/DotNet/SignatureReader.cs deleted file mode 100644 index 4d9dba1..0000000 --- a/Plugins/dnlib/DotNet/SignatureReader.cs +++ /dev/null @@ -1,680 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using dnlib.DotNet.MD; -using dnlib.IO; - -namespace dnlib.DotNet { - /// - /// Helps resolve types - /// - public interface ISignatureReaderHelper { - /// - /// Resolves a - /// - /// A TypeDefOrRef coded token - /// Generic parameter context - /// A or null if - /// is invalid - ITypeDefOrRef ResolveTypeDefOrRef(uint codedToken, GenericParamContext gpContext); - - /// - /// Converts the address of a to a - /// - /// - /// Address of . This is also known as the - /// method table and has the same value as - /// A or null if not supported - TypeSig ConvertRTInternalAddress(IntPtr address); - } - - /// - /// Reads signatures from the #Blob stream - /// - public struct SignatureReader { - // .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; - DataReader reader; - readonly GenericParamContext gpContext; - RecursionCounter recursionCounter; - - /// - /// Reads a signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig) => - ReadSig(readerModule, sig, new GenericParamContext()); - - /// - /// Reads a signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD readerModule, uint sig, GenericParamContext gpContext) { - try { - var reader = new SignatureReader(readerModule, sig, gpContext); - if (reader.reader.Length == 0) - return null; - var csig = reader.ReadSig(); - if (csig is not null) - csig.ExtraData = reader.GetExtraData(); - return csig; - } - catch { - return null; - } - } - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature data - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature) => - ReadSig(module, module.CorLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), new GenericParamContext()); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature data - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) => - ReadSig(module, module.CorLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), gpContext); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature reader - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, DataReader signature) => - ReadSig(module, module.CorLibTypes, signature, new GenericParamContext()); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature reader - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ModuleDefMD module, DataReader signature, GenericParamContext gpContext) => - ReadSig(module, module.CorLibTypes, signature, gpContext); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature data - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) => - ReadSig(helper, corLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), new GenericParamContext()); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature data - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) => - ReadSig(helper, corLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), gpContext); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature reader - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, DataReader signature) => - ReadSig(helper, corLibTypes, signature, new GenericParamContext()); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature reader - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static CallingConventionSig ReadSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, DataReader signature, GenericParamContext gpContext) { - try { - var reader = new SignatureReader(helper, corLibTypes, ref signature, gpContext); - if (reader.reader.Length == 0) - return null; - return reader.ReadSig(); - } - catch { - return null; - } - } - - /// - /// Reads a type signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig) => - ReadTypeSig(readerModule, sig, new GenericParamContext()); - - /// - /// Reads a type signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, GenericParamContext gpContext) { - try { - var reader = new SignatureReader(readerModule, sig, gpContext); - return reader.ReadType(); - } - catch { - return null; - } - } - - /// - /// Reads a type signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// If there's any extra data after the signature, it's saved - /// 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) => - ReadTypeSig(readerModule, sig, new GenericParamContext(), out extraData); - - /// - /// Reads a type signature from the #Blob stream - /// - /// Reader module - /// #Blob stream offset of signature - /// Generic parameter context - /// If there's any extra data after the signature, it's saved - /// here, else this will be null - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD readerModule, uint sig, GenericParamContext gpContext, out byte[] extraData) { - try { - var reader = new SignatureReader(readerModule, sig, gpContext); - TypeSig ts; - try { - ts = reader.ReadType(); - } - catch (IOException) { - reader.reader.Position = 0; - ts = null; - } - extraData = reader.GetExtraData(); - return ts; - } - catch { - extraData = null; - return null; - } - } - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature data - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature) => - ReadTypeSig(module, module.CorLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), new GenericParamContext()); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature data - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, byte[] signature, GenericParamContext gpContext) => - ReadTypeSig(module, module.CorLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), gpContext); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature reader - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, DataReader signature) => - ReadTypeSig(module, module.CorLibTypes, signature, new GenericParamContext()); - - /// - /// Reads a signature - /// - /// The module where the signature is located in - /// The signature reader - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ModuleDefMD module, DataReader signature, GenericParamContext gpContext) => - ReadTypeSig(module, module.CorLibTypes, signature, gpContext); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature data - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature) => - ReadTypeSig(helper, corLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), new GenericParamContext()); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature data - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, byte[] signature, GenericParamContext gpContext) => - ReadTypeSig(helper, corLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), gpContext); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature reader - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, DataReader signature) => - ReadTypeSig(helper, corLibTypes, signature, new GenericParamContext()); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature reader - /// Generic parameter context - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, DataReader signature, GenericParamContext gpContext) => - ReadTypeSig(helper, corLibTypes, signature, gpContext, out var extraData); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature data - /// Generic parameter context - /// If there's any extra data after the signature, it's saved - /// 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) => - ReadTypeSig(helper, corLibTypes, ByteArrayDataReaderFactory.CreateReader(signature), gpContext, out extraData); - - /// - /// Reads a signature - /// - /// Token resolver - /// A instance - /// The signature reader - /// Generic parameter context - /// If there's any extra data after the signature, it's saved - /// here, else this will be null - /// A new instance or null if - /// is invalid. - public static TypeSig ReadTypeSig(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, DataReader signature, GenericParamContext gpContext, out byte[] extraData) { - try { - var reader = new SignatureReader(helper, corLibTypes, ref signature, gpContext); - TypeSig ts; - try { - ts = reader.ReadType(); - } - catch (IOException) { - reader.reader.Position = 0; - ts = null; - } - extraData = reader.GetExtraData(); - return ts; - } - catch { - extraData = null; - return null; - } - } - - /// - /// Constructor - /// - /// Reader module - /// #Blob stream offset of signature - /// Generic parameter context - SignatureReader(ModuleDefMD readerModule, uint sig, GenericParamContext gpContext) { - helper = readerModule; - corLibTypes = readerModule.CorLibTypes; - reader = readerModule.BlobStream.CreateReader(sig); - this.gpContext = gpContext; - recursionCounter = new RecursionCounter(); - } - - /// - /// Constructor - /// - /// Token resolver - /// A instance - /// The signature data - /// Generic parameter context - SignatureReader(ISignatureReaderHelper helper, ICorLibTypes corLibTypes, ref DataReader reader, GenericParamContext gpContext) { - this.helper = helper; - this.corLibTypes = corLibTypes; - this.reader = reader; - this.gpContext = gpContext; - recursionCounter = new RecursionCounter(); - } - - byte[] GetExtraData() { - if (reader.Position == reader.Length) - return null; - return reader.ReadRemainingBytes(); - } - - /// - /// Reads the signature - /// - /// A new instance or null if invalid signature - CallingConventionSig ReadSig() { - if (!recursionCounter.Increment()) - return null; - - CallingConventionSig result; - var callingConvention = (CallingConvention)reader.ReadByte(); - switch (callingConvention & CallingConvention.Mask) { - case CallingConvention.Default: - case CallingConvention.C: - case CallingConvention.StdCall: - case CallingConvention.ThisCall: - case CallingConvention.FastCall: - case CallingConvention.VarArg: - case CallingConvention.Unmanaged: - case CallingConvention.NativeVarArg: - result = ReadMethod(callingConvention); - break; - - case CallingConvention.Field: - result = ReadField(callingConvention); - break; - - case CallingConvention.LocalSig: - result = ReadLocalSig(callingConvention); - break; - - case CallingConvention.Property: - result = ReadProperty(callingConvention); - break; - - case CallingConvention.GenericInst: - result = ReadGenericInstMethod(callingConvention); - break; - - default: - result = null; - break; - } - - recursionCounter.Decrement(); - return result; - } - - /// - /// Reads a - /// - /// First byte of signature - /// A new instance - FieldSig ReadField(CallingConvention callingConvention) => new FieldSig(callingConvention, ReadType()); - - /// - /// Reads a - /// - /// First byte of signature - /// A new instance - MethodSig ReadMethod(CallingConvention callingConvention) => ReadSig(new MethodSig(callingConvention)); - - /// - /// Reads a - /// - /// First byte of signature - /// A new instance - PropertySig ReadProperty(CallingConvention callingConvention) => ReadSig(new PropertySig(callingConvention)); - - T ReadSig(T methodSig) where T : MethodBaseSig { - if (methodSig.Generic) { - if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000) - return null; - methodSig.GenParamCount = count; - } - - if (!reader.TryReadCompressedUInt32(out uint numParams) || numParams > 0x10000 || numParams > reader.BytesLeft) - return null; - - methodSig.RetType = ReadType(); - - var parameters = methodSig.Params; - for (uint i = 0; i < numParams; i++) { - var type = ReadType(); - if (type is SentinelSig) { - if (methodSig.ParamsAfterSentinel is null) - methodSig.ParamsAfterSentinel = parameters = new List((int)(numParams - i)); - i--; - } - else - parameters.Add(type); - } - - return methodSig; - } - - /// - /// Reads a - /// - /// First byte of signature - /// A new instance - LocalSig ReadLocalSig(CallingConvention callingConvention) { - if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft) - return null; - var sig = new LocalSig(callingConvention, count); - var locals = sig.Locals; - for (uint i = 0; i < count; i++) - locals.Add(ReadType()); - return sig; - } - - /// - /// Reads a - /// - /// First byte of signature - /// A new instance - GenericInstMethodSig ReadGenericInstMethod(CallingConvention callingConvention) { - if (!reader.TryReadCompressedUInt32(out uint count) || count > 0x10000 || count > reader.BytesLeft) - return null; - var sig = new GenericInstMethodSig(callingConvention, count); - var args = sig.GenericArguments; - for (uint i = 0; i < count; i++) - args.Add(ReadType()); - return sig; - } - - /// - /// 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(bool allowTypeSpec = false) { - if (!recursionCounter.Increment()) - return null; - - uint num, i; - TypeSig nextType, result = null; - switch ((ElementType)reader.ReadByte()) { - case ElementType.Void: result = corLibTypes.Void; break; - case ElementType.Boolean: result = corLibTypes.Boolean; break; - case ElementType.Char: result = corLibTypes.Char; break; - case ElementType.I1: result = corLibTypes.SByte; break; - case ElementType.U1: result = corLibTypes.Byte; break; - case ElementType.I2: result = corLibTypes.Int16; break; - case ElementType.U2: result = corLibTypes.UInt16; break; - case ElementType.I4: result = corLibTypes.Int32; break; - case ElementType.U4: result = corLibTypes.UInt32; break; - case ElementType.I8: result = corLibTypes.Int64; break; - case ElementType.U8: result = corLibTypes.UInt64; break; - case ElementType.R4: result = corLibTypes.Single; break; - case ElementType.R8: result = corLibTypes.Double; break; - case ElementType.String: result = corLibTypes.String; break; - case ElementType.TypedByRef:result = corLibTypes.TypedReference; break; - case ElementType.I: result = corLibTypes.IntPtr; break; - case ElementType.U: result = corLibTypes.UIntPtr; break; - case ElementType.Object: result = corLibTypes.Object; break; - - case ElementType.Ptr: result = new PtrSig(ReadType()); break; - case ElementType.ByRef: result = new ByRefSig(ReadType()); 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; - 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; - - case ElementType.Var: - if (!reader.TryReadCompressedUInt32(out num)) - break; - result = new GenericVar(num, gpContext.Type); - break; - - case ElementType.MVar: - if (!reader.TryReadCompressedUInt32(out num)) - break; - result = new GenericMVar(num, gpContext.Method); - break; - - case ElementType.ValueArray: - nextType = ReadType(); - if (!reader.TryReadCompressedUInt32(out num)) - break; - result = new ValueArraySig(nextType, num); - break; - - case ElementType.Module: - if (!reader.TryReadCompressedUInt32(out num)) - break; - result = new ModuleSig(num, ReadType()); - break; - - case ElementType.GenericInst: - nextType = ReadType(); - if (!reader.TryReadCompressedUInt32(out num) || num > 0x10000 || num > reader.BytesLeft) - break; - var genericInstSig = new GenericInstSig(nextType as ClassOrValueTypeSig, num); - var args = genericInstSig.GenericArguments; - for (i = 0; i < num; i++) - args.Add(ReadType()); - result = genericInstSig; - break; - - case ElementType.Array: - nextType = 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 > rank) - break; - var sizes = new List((int)num); - for (i = 0; i < num; i++) { - if (!reader.TryReadCompressedUInt32(out uint size)) - goto exit; - sizes.Add(size); - } - if (!reader.TryReadCompressedUInt32(out num)) - break; - if (num > rank) - break; - var lowerBounds = new List((int)num); - for (i = 0; i < num; i++) { - if (!reader.TryReadCompressedInt32(out int size)) - goto exit; - lowerBounds.Add(size); - } - result = new ArraySig(nextType, rank, sizes, lowerBounds); - break; - - case ElementType.Internal: - IntPtr address; - if (IntPtr.Size == 4) - address = new IntPtr(reader.ReadInt32()); - else - address = new IntPtr(reader.ReadInt64()); - result = helper.ConvertRTInternalAddress(address); - break; - - case ElementType.End: - case ElementType.R: - default: - result = null; - break; - } -exit: - recursionCounter.Decrement(); - return result; - } - - ITypeDefOrRef ReadTypeDefOrRef(bool allowTypeSpec) { - if (!reader.TryReadCompressedUInt32(out uint codedToken)) - return null; - if (!allowTypeSpec && CodedToken.TypeDefOrRef.Decode2(codedToken).Table == Table.TypeSpec) - return null; - return helper.ResolveTypeDefOrRef(codedToken, default); - } - } -} diff --git a/Plugins/dnlib/DotNet/StandAloneSig.cs b/Plugins/dnlib/DotNet/StandAloneSig.cs deleted file mode 100644 index 84c3625..0000000 --- a/Plugins/dnlib/DotNet/StandAloneSig.cs +++ /dev/null @@ -1,177 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the StandAloneSig table - /// - public abstract class StandAloneSig : IHasCustomAttribute, IHasCustomDebugInformation, IContainsGenericParameter { - /// - /// The row id in its table - /// - protected uint rid; - - /// - public MDToken MDToken => new MDToken(Table.StandAloneSig, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int HasCustomAttributeTag => 11; - - /// - /// From column StandAloneSig.Signature - /// - public CallingConventionSig Signature { - get => signature; - set => signature = value; - } - /// - protected CallingConventionSig signature; - - /// - /// 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 => 11; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// Gets/sets the method sig - /// - public MethodSig MethodSig { - get => signature as MethodSig; - set => signature = value; - } - - /// - /// Gets/sets the locals sig - /// - public LocalSig LocalSig { - get => signature as LocalSig; - set => signature = value; - } - - /// - public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - } - - /// - /// A StandAloneSig row created by the user and not present in the original .NET file - /// - public class StandAloneSigUser : StandAloneSig { - /// - /// Default constructor - /// - public StandAloneSigUser() { - } - - /// - /// Constructor - /// - /// A locals sig - public StandAloneSigUser(LocalSig localSig) => signature = localSig; - - /// - /// Constructor - /// - /// A method sig - public StandAloneSigUser(MethodSig methodSig) => signature = methodSig; - } - - /// - /// Created from a row in the StandAloneSig table - /// - sealed class StandAloneSigMD : StandAloneSig, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - - /// - public uint OrigRid => origRid; - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.StandAloneSig, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - /// Constructor - /// - /// The module which contains this StandAloneSig row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public StandAloneSigMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.StandAloneSigTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"StandAloneSig rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - bool b = readerModule.TablesStream.TryReadStandAloneSigRow(origRid, out var row); - Debug.Assert(b); - signature = readerModule.ReadSignature(row.Signature, gpContext); - } - } -} diff --git a/Plugins/dnlib/DotNet/StrongNameKey.cs b/Plugins/dnlib/DotNet/StrongNameKey.cs deleted file mode 100644 index 25016a7..0000000 --- a/Plugins/dnlib/DotNet/StrongNameKey.cs +++ /dev/null @@ -1,528 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.Serialization; -using System.Security.Cryptography; -using System.Threading; - -namespace dnlib.DotNet { - /// - /// Thrown if the strong name key or public key is invalid - /// - [Serializable] - public class InvalidKeyException : Exception { - /// - /// Default constructor - /// - public InvalidKeyException() { - } - - /// - /// Constructor - /// - /// Error message - public InvalidKeyException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Error message - /// Other exception - public InvalidKeyException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected InvalidKeyException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Type of signature algorithm. See WinCrypt.h in the Windows SDK - /// - public enum SignatureAlgorithm : uint { - /// - /// RSA signature algorithm - /// - CALG_RSA_SIGN = 0x00002400, - } - - static class StrongNameUtils { - public static byte[] ReadBytesReverse(this BinaryReader reader, int len) { - var data = reader.ReadBytes(len); - if (data.Length != len) - throw new InvalidKeyException("Can't read more bytes"); - Array.Reverse(data); - return data; - } - - public static void WriteReverse(this BinaryWriter writer, byte[] data) { - var d = (byte[])data.Clone(); - Array.Reverse(d); - writer.Write(d); - } - } - - /// - /// A public key - /// - public sealed class StrongNamePublicKey { - const uint RSA1_SIG = 0x31415352; - readonly SignatureAlgorithm signatureAlgorithm; - readonly AssemblyHashAlgorithm hashAlgorithm; - readonly byte[] modulus; - readonly byte[] publicExponent; - - /// - /// Gets/sets the signature algorithm - /// - public SignatureAlgorithm SignatureAlgorithm => signatureAlgorithm; - - /// - /// Gets/sets the hash algorithm - /// - public AssemblyHashAlgorithm HashAlgorithm => hashAlgorithm; - - /// - /// Gets/sets the modulus - /// - public byte[] Modulus => modulus; - - /// - /// Gets/sets the public exponent - /// - public byte[] PublicExponent => publicExponent; - - /// - /// Default constructor - /// - public StrongNamePublicKey() { - } - - /// - /// Constructor - /// - /// Modulus - /// Public exponent - public StrongNamePublicKey(byte[] modulus, byte[] publicExponent) - : this(modulus, publicExponent, AssemblyHashAlgorithm.SHA1, SignatureAlgorithm.CALG_RSA_SIGN) { - } - - /// - /// Constructor - /// - /// Modulus - /// Public exponent - /// Hash algorithm - public StrongNamePublicKey(byte[] modulus, byte[] publicExponent, AssemblyHashAlgorithm hashAlgorithm) - : this(modulus, publicExponent, hashAlgorithm, SignatureAlgorithm.CALG_RSA_SIGN) { - } - - /// - /// Constructor - /// - /// Modulus - /// Public exponent - /// Hash algorithm - /// Signature algorithm - public StrongNamePublicKey(byte[] modulus, byte[] publicExponent, AssemblyHashAlgorithm hashAlgorithm, SignatureAlgorithm signatureAlgorithm) { - this.signatureAlgorithm = signatureAlgorithm; - this.hashAlgorithm = hashAlgorithm; - this.modulus = modulus; - this.publicExponent = publicExponent; - } - - /// - /// Constructor - /// - /// Public key - public StrongNamePublicKey(PublicKey pk) - : this(pk.Data) { - } - - /// - /// Constructor - /// - /// Public key data - /// Strong name key is invalid - public StrongNamePublicKey(byte[] pk) : this(new BinaryReader(new MemoryStream(pk))) { } - - /// - /// Constructor - /// - /// Public key file - /// Strong name key is invalid - public StrongNamePublicKey(string filename) : this(File.ReadAllBytes(filename)) { } - - /// - /// Constructor - /// - /// Public key stream - /// Strong name key is invalid - public StrongNamePublicKey(Stream stream) : this(new BinaryReader(stream)) { } - - /// - /// Constructor - /// - /// Public key reader - /// Strong name key is invalid - public StrongNamePublicKey(BinaryReader reader) { - try { - // Read PublicKeyBlob - signatureAlgorithm = (SignatureAlgorithm)reader.ReadUInt32(); - hashAlgorithm = (AssemblyHashAlgorithm)reader.ReadUInt32(); - /*int pkLen = */reader.ReadInt32(); - - // Read PUBLICKEYSTRUC - if (reader.ReadByte() != 6) - throw new InvalidKeyException("Not a public key"); - if (reader.ReadByte() != 2) - throw new InvalidKeyException("Invalid version"); - reader.ReadUInt16(); // reserved - if ((SignatureAlgorithm)reader.ReadUInt32() != SignatureAlgorithm.CALG_RSA_SIGN) - throw new InvalidKeyException("Not RSA sign"); - - // Read RSAPUBKEY - if (reader.ReadUInt32() != RSA1_SIG) // magic = RSA1 - throw new InvalidKeyException("Invalid RSA1 magic"); - uint bitLength = reader.ReadUInt32(); - publicExponent = reader.ReadBytesReverse(4); - - modulus = reader.ReadBytesReverse((int)(bitLength / 8)); - } - catch (IOException ex) { - throw new InvalidKeyException("Invalid public key", ex); - } - } - - /// - /// Creates a public key blob - /// - 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) - throw new ArgumentException("Signature algorithm must be RSA"); - var outStream = new MemoryStream(); - var writer = new BinaryWriter(outStream); - writer.Write((uint)sigAlg); // SigAlgID - writer.Write((uint)hashAlg); // HashAlgID - writer.Write(0x14 + modulus.Length);// cbPublicKey - writer.Write((byte)6); // bType (public key) - writer.Write((byte)2); // bVersion - writer.Write((ushort)0); // reserved - writer.Write((uint)sigAlg); // aiKeyAlg - writer.Write(RSA1_SIG); // magic (RSA1) - writer.Write(modulus.Length * 8); // bitlen - writer.WriteReverse(publicExponent);// pubexp - writer.WriteReverse(modulus); // modulus - return outStream.ToArray(); - } - - /// - public override string ToString() => Utils.ToHex(CreatePublicKey(), false); - } - - /// - /// Stores a strong name key pair - /// - public sealed class StrongNameKey { - const uint RSA2_SIG = 0x32415352; - byte[] publicKey; - readonly AssemblyHashAlgorithm hashAlg; - readonly byte[] publicExponent; - readonly byte[] modulus; - readonly byte[] prime1; - readonly byte[] prime2; - readonly byte[] exponent1; - readonly byte[] exponent2; - readonly byte[] coefficient; - readonly byte[] privateExponent; - - /// - /// Gets the public key - /// - public byte[] PublicKey { - get { - if (publicKey is null) - Interlocked.CompareExchange(ref publicKey, CreatePublicKey(), null); - return publicKey; - } - } - - /// - /// Gets the strong name signature size in bytes - /// - public int SignatureSize => modulus.Length; - - /// - /// Gets the public key hash algorithm. It's usually - /// - public AssemblyHashAlgorithm HashAlgorithm => hashAlg; - - /// - /// Gets the public exponent - /// - public byte[] PublicExponent => publicExponent; - - /// - /// Gets the modulus - /// - public byte[] Modulus => modulus; - - /// - /// Gets prime1 - /// - public byte[] Prime1 => prime1; - - /// - /// Gets prime2 - /// - public byte[] Prime2 => prime2; - - /// - /// Gets exponent1 - /// - public byte[] Exponent1 => exponent1; - - /// - /// Gets exponent2 - /// - public byte[] Exponent2 => exponent2; - - /// - /// Gets the coefficient - /// - public byte[] Coefficient => coefficient; - - /// - /// Gets the private exponent - /// - public byte[] PrivateExponent => privateExponent; - - /// - /// Constructor - /// - /// Strong name key data - /// Strong name key is invalid - public StrongNameKey(byte[] keyData) : this(new BinaryReader(new MemoryStream(keyData))) { } - - /// - /// Constructor - /// - /// Strong name key file - /// Strong name key is invalid - public StrongNameKey(string filename) : this(File.ReadAllBytes(filename)) { } - - /// - /// Constructor - /// - /// Strong name key stream - /// Strong name key is invalid - public StrongNameKey(Stream stream) : this(new BinaryReader(stream)) { } - - /// - /// Constructor - /// - /// Strong name key reader - /// Strong name key is invalid - public StrongNameKey(BinaryReader reader) { - /* - * Links: - * 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) - * unsigned int HashAlgID; // hash alg used to create the sig (usually 00008004 = CALG_SHA1) - * ULONG cbPublicKey; // Size of the data that follows - * // the rest is here - * } - * - * typedef struct _PUBLICKEYSTRUC { - * BYTE bType; - * BYTE bVersion; - * WORD reserved; - * ALG_ID aiKeyAlg; - * } BLOBHEADER, PUBLICKEYSTRUC; - * - * typedef struct _RSAPUBKEY { - * DWORD magic; - * DWORD bitlen; - * DWORD pubexp; - * } RSAPUBKEY; - * - * Format of public key - * PublicKeyBlob - * PUBLICKEYSTRUC publickeystruc; - * RSAPUBKEY rsapubkey; - * BYTE modulus[rsapubkey.bitlen/8] - * - * Format of public/private key pair - * PUBLICKEYSTRUC publickeystruc; - * RSAPUBKEY rsapubkey; - * BYTE modulus[rsapubkey.bitlen/8]; - * BYTE prime1[rsapubkey.bitlen/16]; // aka P - * BYTE prime2[rsapubkey.bitlen/16]; // aka Q - * BYTE exponent1[rsapubkey.bitlen/16]; // aka DP - * BYTE exponent2[rsapubkey.bitlen/16]; // aka DQ - * BYTE coefficient[rsapubkey.bitlen/16]; // aka IQ - * BYTE privateExponent[rsapubkey.bitlen/8];// aka D - */ - - try { - publicKey = null; - - // Read PUBLICKEYSTRUC - if (reader.ReadByte() != 7) - throw new InvalidKeyException("Not a public/private key pair"); - if (reader.ReadByte() != 2) - throw new InvalidKeyException("Invalid version"); - reader.ReadUInt16(); // reserved - if ((SignatureAlgorithm)reader.ReadUInt32() != SignatureAlgorithm.CALG_RSA_SIGN) - throw new InvalidKeyException("Not RSA sign"); - - // Read RSAPUBKEY - if (reader.ReadUInt32() != RSA2_SIG) // magic = RSA2 - throw new InvalidKeyException("Invalid RSA2 magic"); - uint bitLength = reader.ReadUInt32(); - publicExponent = reader.ReadBytesReverse(4); - - int len8 = (int)(bitLength / 8); - int len16 = (int)(bitLength / 16); - - // Read the rest - modulus = reader.ReadBytesReverse(len8); - prime1 = reader.ReadBytesReverse(len16); - prime2 = reader.ReadBytesReverse(len16); - exponent1 = reader.ReadBytesReverse(len16); - exponent2 = reader.ReadBytesReverse(len16); - coefficient = reader.ReadBytesReverse(len16); - privateExponent = reader.ReadBytesReverse(len8); - } - catch (IOException ex) { - throw new InvalidKeyException("Couldn't read strong name key", ex); - } - } - - StrongNameKey(AssemblyHashAlgorithm hashAlg, byte[] publicExponent, byte[] modulus, byte[] prime1, byte[] prime2, byte[] exponent1, byte[] exponent2, byte[] coefficient, byte[] privateExponent) { - this.hashAlg = hashAlg; - this.publicExponent = publicExponent; - this.modulus = modulus; - this.prime1 = prime1; - this.prime2 = prime2; - this.exponent1 = exponent1; - this.exponent2 = exponent2; - this.coefficient = coefficient; - this.privateExponent = privateExponent; - } - - /// - /// Creates a strong name key with a new hash algorithm - /// - /// Algorithm - /// - public StrongNameKey WithHashAlgorithm(AssemblyHashAlgorithm hashAlgorithm) { - if (hashAlg == hashAlgorithm) - return this; - return new StrongNameKey(hashAlgorithm, publicExponent, modulus, prime1, prime2, exponent1, exponent2, coefficient, privateExponent); - } - - byte[] CreatePublicKey() { - var halg = hashAlg == 0 ? AssemblyHashAlgorithm.SHA1 : hashAlg; - return StrongNamePublicKey.CreatePublicKey(SignatureAlgorithm.CALG_RSA_SIGN, halg, modulus, publicExponent); - } - - /// - /// Creates an instance - /// - public RSA CreateRSA() { - RSAParameters rsaParams; - rsaParams = new RSAParameters { - Exponent = publicExponent, - Modulus = modulus, - P = prime1, - Q = prime2, - DP = exponent1, - DQ = exponent2, - InverseQ = coefficient, - D = privateExponent, - }; - var rsa = RSA.Create(); - try { - rsa.ImportParameters(rsaParams); - return rsa; - } - catch { - ((IDisposable)rsa).Dispose(); - throw; - } - } - - /// - /// Creates a strong name blob - /// - public byte[] CreateStrongName() { - var outStream = new MemoryStream(); - var writer = new BinaryWriter(outStream); - writer.Write((byte)7); // bType (public/private key) - writer.Write((byte)2); // bVersion - writer.Write((ushort)0); // reserved - writer.Write((uint)SignatureAlgorithm.CALG_RSA_SIGN); // aiKeyAlg - writer.Write(RSA2_SIG); // magic (RSA2) - writer.Write(modulus.Length * 8); // bitlen - writer.WriteReverse(publicExponent); - writer.WriteReverse(modulus); - writer.WriteReverse(prime1); - writer.WriteReverse(prime2); - writer.WriteReverse(exponent1); - writer.WriteReverse(exponent2); - writer.WriteReverse(coefficient); - writer.WriteReverse(privateExponent); - return outStream.ToArray(); - } - - /// - /// Creates a counter signature, just like - /// sn -a IdentityPubKey.snk IdentityKey.snk SignaturePubKey.snk can do. - /// The public key sn prints is 's value. - /// - /// Identity public key - /// Identity strong name key pair - /// Signature public key - /// The counter signature as a hex string - public static string CreateCounterSignatureAsString(StrongNamePublicKey identityPubKey, StrongNameKey identityKey, StrongNamePublicKey signaturePubKey) { - var counterSignature = CreateCounterSignature(identityPubKey, identityKey, signaturePubKey); - return Utils.ToHex(counterSignature, false); - } - - /// - /// Creates a counter signature, just like - /// sn -a IdentityPubKey.snk IdentityKey.snk SignaturePubKey.snk can do. - /// The public key sn prints is 's value. - /// - /// Identity public key - /// Identity strong name key pair - /// Signature public key - /// The counter signature - public static byte[] CreateCounterSignature(StrongNamePublicKey identityPubKey, StrongNameKey identityKey, StrongNamePublicKey signaturePubKey) { - var hash = AssemblyHash.Hash(signaturePubKey.CreatePublicKey(), identityPubKey.HashAlgorithm); - using (var rsa = identityKey.CreateRSA()) { - var rsaFmt = new RSAPKCS1SignatureFormatter(rsa); - string hashName = identityPubKey.HashAlgorithm.GetName(); - rsaFmt.SetHashAlgorithm(hashName); - var snSig = rsaFmt.CreateSignature(hash); - Array.Reverse(snSig); - return snSig; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/StrongNameSigner.cs b/Plugins/dnlib/DotNet/StrongNameSigner.cs deleted file mode 100644 index 75e9379..0000000 --- a/Plugins/dnlib/DotNet/StrongNameSigner.cs +++ /dev/null @@ -1,171 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Security.Cryptography; - -namespace dnlib.DotNet { - /// - /// Strong name signs an assembly. It supports normal strong name signing and the new - /// (.NET Framework 4.5) enhanced strong name signing. - /// - public readonly struct StrongNameSigner { - readonly Stream stream; - readonly long baseOffset; - - /// - /// Constructor - /// - /// .NET PE file stream - public StrongNameSigner(Stream stream) - : this(stream, 0) { - } - - /// - /// Constructor - /// - /// .NET PE file stream - /// Offset in of the first byte of - /// the PE file. - public StrongNameSigner(Stream stream, long baseOffset) { - this.stream = stream; - this.baseOffset = baseOffset; - } - - /// - /// Calculates the strong name signature and writes it to the stream. The signature - /// is also returned. - /// - /// Strong name key used for signing - /// Offset (relative to the start of the PE file) of the strong - /// name signature. - /// The strong name signature - public byte[] WriteSignature(StrongNameKey snk, long snSigOffset) { - var sign = CalculateSignature(snk, snSigOffset); - stream.Position = baseOffset + snSigOffset; - stream.Write(sign, 0, sign.Length); - return sign; - } - - /// - /// Calculates and returns the strong name signature - /// - /// Strong name key used for signing - /// Offset (relative to start of PE file) of the strong - /// name signature. - /// The strong name signature - public byte[] CalculateSignature(StrongNameKey snk, long snSigOffset) { - uint snSigSize = (uint)snk.SignatureSize; - var hashAlg = snk.HashAlgorithm == 0 ? AssemblyHashAlgorithm.SHA1 : snk.HashAlgorithm; - var hash = StrongNameHashData(hashAlg, snSigOffset, snSigSize); - var snSig = GetStrongNameSignature(snk, hashAlg, hash); - if (snSig.Length != snSigSize) - throw new InvalidOperationException("Invalid strong name signature size"); - return snSig; - } - - /// - /// Strong name hashes the .NET file - /// - /// Hash algorithm - /// Strong name sig offset (relative to start of .NET PE file) - /// Size of strong name signature - /// The strong name hash of the .NET file - byte[] StrongNameHashData(AssemblyHashAlgorithm hashAlg, long snSigOffset, uint snSigSize) { - var reader = new BinaryReader(stream); - - snSigOffset += baseOffset; - long snSigOffsetEnd = snSigOffset + snSigSize; - - using (var hasher = new AssemblyHash(hashAlg)) { - 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. - stream.Position = baseOffset + 0x3C; - uint ntHeadersOffs = reader.ReadUInt32(); - stream.Position = baseOffset; - hasher.Hash(stream, ntHeadersOffs, buffer); - - // Hash NT headers, but hash authenticode + checksum as 0s - stream.Position += 6; - int numSections = reader.ReadUInt16(); - stream.Position -= 8; - hasher.Hash(stream, 0x18, buffer); // magic + FileHeader - - bool is32bit = reader.ReadUInt16() == 0x010B; - stream.Position -= 2; - int optHeaderSize = is32bit ? 0x60 : 0x70; - if (stream.Read(buffer, 0, optHeaderSize) != optHeaderSize) - throw new IOException("Could not read data"); - // Clear checksum - for (int i = 0; i < 4; i++) - buffer[0x40 + i] = 0; - hasher.Hash(buffer, 0, optHeaderSize); - - const int imageDirsSize = 16 * 8; - if (stream.Read(buffer, 0, imageDirsSize) != imageDirsSize) - throw new IOException("Could not read data"); - // Clear authenticode data dir - for (int i = 0; i < 8; i++) - buffer[4 * 8 + i] = 0; - hasher.Hash(buffer, 0, imageDirsSize); - - // Hash section headers - long sectHeadersOffs = stream.Position; - hasher.Hash(stream, (uint)numSections * 0x28, buffer); - - // Hash all raw section data but make sure we don't hash the location - // where the strong name signature will be stored. - for (int i = 0; i < numSections; i++) { - stream.Position = sectHeadersOffs + i * 0x28 + 0x10; - uint sizeOfRawData = reader.ReadUInt32(); - uint pointerToRawData = reader.ReadUInt32(); - - stream.Position = baseOffset + pointerToRawData; - while (sizeOfRawData > 0) { - var pos = stream.Position; - - if (snSigOffset <= pos && pos < snSigOffsetEnd) { - uint skipSize = (uint)(snSigOffsetEnd - pos); - if (skipSize >= sizeOfRawData) - break; - sizeOfRawData -= skipSize; - stream.Position += skipSize; - continue; - } - - if (pos >= snSigOffsetEnd) { - hasher.Hash(stream, sizeOfRawData, buffer); - break; - } - - uint maxLen = (uint)Math.Min(snSigOffset - pos, sizeOfRawData); - hasher.Hash(stream, maxLen, buffer); - sizeOfRawData -= maxLen; - } - } - - return hasher.ComputeHash(); - } - } - - /// - /// Returns the strong name signature - /// - /// Strong name key - /// Hash algorithm - /// Strong name hash of the .NET PE file - /// Strong name signature - byte[] GetStrongNameSignature(StrongNameKey snk, AssemblyHashAlgorithm hashAlg, byte[] hash) { - using (var rsa = snk.CreateRSA()) { - var rsaFmt = new RSAPKCS1SignatureFormatter(rsa); - string hashName = hashAlg.GetName() ?? AssemblyHashAlgorithm.SHA1.GetName(); - rsaFmt.SetHashAlgorithm(hashName); - var snSig = rsaFmt.CreateSignature(hash); - Array.Reverse(snSig); - return snSig; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/TIAHelper.cs b/Plugins/dnlib/DotNet/TIAHelper.cs deleted file mode 100644 index 3fc0349..0000000 --- a/Plugins/dnlib/DotNet/TIAHelper.cs +++ /dev/null @@ -1,221 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -// See coreclr/src/vm/siginfo.cpp - -using System; -using System.Diagnostics; - -namespace dnlib.DotNet { - /// - /// System.Runtime.InteropServices.TypeIdentifierAttribute helper code used by - /// - static class TIAHelper { - readonly struct Info : IEquatable { - public readonly UTF8String Scope; - public readonly UTF8String Identifier; - - public Info(UTF8String scope, UTF8String identifier) { - Scope = scope; - Identifier = identifier; - } - - public bool Equals(Info other) => stricmp(Scope, other.Scope) && UTF8String.Equals(Identifier, other.Identifier); - - static bool stricmp(UTF8String a, UTF8String b) { - var da = a?.Data; - var db = b?.Data; - if (da == db) - return true; - if (da is null || db is null) - return false; - if (da.Length != db.Length) - return false; - for (int i = 0; i < da.Length; i++) { - byte ba = da[i], bb = db[i]; - if ((byte)'A' <= ba && ba <= (byte)'Z') - ba = (byte)(ba - 'A' + 'a'); - if ((byte)'A' <= bb && bb <= (byte)'Z') - bb = (byte)(bb - 'A' + 'a'); - if (ba != bb) - return false; - } - return true; - } - } - - static Info? GetInfo(TypeDef td) { - 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 is not null) { - if (tia.ConstructorArguments.Count >= 2) { - if (tia.ConstructorArguments[0].Type.GetElementType() != ElementType.String) - return null; - if (tia.ConstructorArguments[1].Type.GetElementType() != ElementType.String) - return null; - scope = tia.ConstructorArguments[0].Value as UTF8String ?? tia.ConstructorArguments[0].Value as string; - identifier = tia.ConstructorArguments[1].Value as UTF8String ?? tia.ConstructorArguments[1].Value as string; - } - } - else { - var asm = td.Module?.Assembly; - if (asm is null) - return null; - bool isTypeLib = asm.CustomAttributes.IsDefined("System.Runtime.InteropServices.ImportedFromTypeLibAttribute") || - asm.CustomAttributes.IsDefined("System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute"); - if (!isTypeLib) - return null; - } - - if (UTF8String.IsNull(identifier)) { - CustomAttribute gca; - if (td.IsInterface && td.IsImport) - gca = td.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); - else { - var asm = td.Module?.Assembly; - if (asm is null) - return null; - gca = asm.CustomAttributes.Find("System.Runtime.InteropServices.GuidAttribute"); - } - if (gca is null) - return null; - if (gca.ConstructorArguments.Count < 1) - return null; - if (gca.ConstructorArguments[0].Type.GetElementType() != ElementType.String) - return null; - scope = gca.ConstructorArguments[0].Value as UTF8String ?? gca.ConstructorArguments[0].Value as string; - var ns = td.Namespace; - var name = td.Name; - if (UTF8String.IsNullOrEmpty(ns)) - identifier = name; - else if (UTF8String.IsNullOrEmpty(name)) - identifier = new UTF8String(Concat(ns.Data, (byte)'.', Array2.Empty())); - else - identifier = new UTF8String(Concat(ns.Data, (byte)'.', name.Data)); - } - return new Info(scope, identifier); - } - - static byte[] Concat(byte[] a, byte b, byte[] c) { - var data = new byte[a.Length + 1 + c.Length]; - for (int i = 0; i < a.Length; i++) - data[i] = a[i]; - data[a.Length] = b; - for (int i = 0, j = a.Length + 1; i < c.Length; i++, j++) - data[j] = c[i]; - return data; - } - - internal static bool IsTypeDefEquivalent(TypeDef td) => GetInfo(td) is not null && CheckEquivalent(td); - - static bool CheckEquivalent(TypeDef td) { - Debug.Assert(td is not null); - - for (int i = 0; td is not null && i < 1000; i++) { - if (i != 0) { - var info = GetInfo(td); - if (info is null) - return false; - } - - bool f; - if (td.IsInterface) - f = td.IsImport || td.CustomAttributes.IsDefined("System.Runtime.InteropServices.ComEventInterfaceAttribute"); - else - f = td.IsValueType || td.IsDelegate; - if (!f) - return false; - if (td.GenericParameters.Count > 0) - return false; - - var declType = td.DeclaringType; - if (declType is null) - return td.IsPublic; - - if (!td.IsNestedPublic) - return false; - td = declType; - } - - return false; - } - - public static bool Equivalent(TypeDef td1, TypeDef td2) { - var info1 = GetInfo(td1); - if (info1 is null) - return false; - var info2 = GetInfo(td2); - if (info2 is null) - return false; - if (!CheckEquivalent(td1) || !CheckEquivalent(td2)) - return false; - if (!info1.Value.Equals(info2.Value)) - return false; - - // Caller has already compared names of the types and any declaring types - - for (int i = 0; i < 1000; i++) { - if (td1.IsInterface) { - if (!td2.IsInterface) - return false; - } - else { - var bt1 = td1.BaseType; - var bt2 = td2.BaseType; - if (bt1 is null || bt2 is null) - return false; - if (td1.IsDelegate) { - if (!td2.IsDelegate) - return false; - if (!DelegateEquals(td1, td2)) - return false; - } - else if (td1.IsValueType) { - if (td1.IsEnum != td2.IsEnum) - return false; - if (!td2.IsValueType) - return false; - if (!ValueTypeEquals(td1, td2, td1.IsEnum)) - return false; - } - else - return false; - } - - td1 = td1.DeclaringType; - td2 = td2.DeclaringType; - if (td1 is null && td2 is null) - break; - if (td1 is null || td2 is null) - return false; - } - - return true; - } - - static bool DelegateEquals(TypeDef td1, TypeDef td2) { - var invoke1 = td1.FindMethod(InvokeString); - var invoke2 = td2.FindMethod(InvokeString); - if (invoke1 is null || invoke2 is null) - return false; - - //TODO: Compare method signatures. Prevent infinite recursion... - - return true; - } - static readonly UTF8String InvokeString = new UTF8String("Invoke"); - - static bool ValueTypeEquals(TypeDef td1, TypeDef td2, bool isEnum) { - if (td1.Methods.Count != 0 || td2.Methods.Count != 0) - return false; - - //TODO: Compare the fields. Prevent infinite recursion... - - return true; - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeAttributes.cs b/Plugins/dnlib/DotNet/TypeAttributes.cs deleted file mode 100644 index 2ae0aa2..0000000 --- a/Plugins/dnlib/DotNet/TypeAttributes.cs +++ /dev/null @@ -1,87 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.DotNet { - /// - /// TypeDef and ExportedType flags. See CorHdr.h/CorTypeAttr - /// - [Flags] - public enum TypeAttributes : uint { - /// Use this mask to retrieve the type visibility information. - VisibilityMask = 0x00000007, - /// Class is not public scope. - NotPublic = 0x00000000, - /// Class is public scope. - Public = 0x00000001, - /// Class is nested with public visibility. - NestedPublic = 0x00000002, - /// Class is nested with private visibility. - NestedPrivate = 0x00000003, - /// Class is nested with family visibility. - NestedFamily = 0x00000004, - /// Class is nested with assembly visibility. - NestedAssembly = 0x00000005, - /// Class is nested with family and assembly visibility. - NestedFamANDAssem = 0x00000006, - /// Class is nested with family or assembly visibility. - NestedFamORAssem = 0x00000007, - - /// Use this mask to retrieve class layout information - LayoutMask = 0x00000018, - /// Class fields are auto-laid out - AutoLayout = 0x00000000, - /// Class fields are laid out sequentially - SequentialLayout = 0x00000008, - /// Layout is supplied explicitly - ExplicitLayout = 0x00000010, - - /// Use this mask to retrieve class semantics information. - ClassSemanticsMask = 0x00000020, - /// Use this mask to retrieve class semantics information. - ClassSemanticMask = ClassSemanticsMask, - /// Type is a class. - Class = 0x00000000, - /// Type is an interface. - Interface = 0x00000020, - - /// Class is abstract - Abstract = 0x00000080, - /// Class is concrete and may not be extended - Sealed = 0x00000100, - /// Class name is special. Name describes how. - SpecialName = 0x00000400, - - /// Class / interface is imported - Import = 0x00001000, - /// The class is Serializable. - Serializable = 0x00002000, - /// The type is a Windows Runtime type - WindowsRuntime = 0x00004000, - - /// Use StringFormatMask to retrieve string information for native interop - StringFormatMask = 0x00030000, - /// LPTSTR is interpreted as ANSI in this class - AnsiClass = 0x00000000, - /// LPTSTR is interpreted as UNICODE - UnicodeClass = 0x00010000, - /// LPTSTR is interpreted automatically - AutoClass = 0x00020000, - /// A non-standard encoding specified by CustomFormatMask - CustomFormatClass = 0x00030000, - /// Use this mask to retrieve non-standard encoding information for native interop. The meaning of the values of these 2 bits is unspecified. - CustomFormatMask = 0x00C00000, - - /// Initialize the class any time before first static field access. - BeforeFieldInit = 0x00100000, - /// This ExportedType is a type forwarder. - Forwarder = 0x00200000, - - /// Flags reserved for runtime use. - ReservedMask = 0x00040800, - /// Runtime should check name encoding. - RTSpecialName = 0x00000800, - /// Class has security associate with it. - HasSecurity = 0x00040000, - } -} diff --git a/Plugins/dnlib/DotNet/TypeDef.cs b/Plugins/dnlib/DotNet/TypeDef.cs deleted file mode 100644 index e46b36b..0000000 --- a/Plugins/dnlib/DotNet/TypeDef.cs +++ /dev/null @@ -1,2332 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Threading; -using dnlib.Utils; -using dnlib.DotNet.MD; -using dnlib.DotNet.Emit; -using dnlib.Threading; -using dnlib.DotNet.Pdb; -using System.Diagnostics; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the TypeDef table - /// - public abstract class TypeDef : ITypeDefOrRef, IHasCustomAttribute, IHasDeclSecurity, IMemberRefParent, ITypeOrMethodDef, IHasCustomDebugInformation, IListListener, IListListener, IListListener, IListListener, IListListener, IListListener, IMemberRefResolver, IMemberDef { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.TypeDef, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int TypeDefOrRefTag => 0; - - /// - public int HasCustomAttributeTag => 3; - - /// - public int HasDeclSecurityTag => 0; - - /// - public int MemberRefParentTag => 0; - - /// - public int TypeOrMethodDefTag => 0; - - /// - int IGenericParameterProvider.NumberOfGenericParameters => GenericParameters.Count; - - /// - string IType.TypeName => Name; - - /// - public string ReflectionName => FullNameFactory.Name(this, true, null); - - /// - string IType.Namespace => Namespace; - - /// - public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); - - /// - public string FullName => FullNameFactory.FullName(this, false, null, null); - - /// - public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); - - /// - public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); - - /// - public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); - - /// - public IScope Scope => Module; - - /// - public ITypeDefOrRef ScopeType => this; - - /// - /// Always returns false since a does not contain any - /// or . - /// - public bool ContainsGenericParameter => false; - - /// - public ModuleDef Module => FullNameFactory.OwnerModule(this); - - /// - /// Gets/sets the owner module - /// - internal ModuleDef Module2 { - get { - if (!module2_isInitialized) - InitializeModule2(); - return module2; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - module2 = value; - module2_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected ModuleDef module2; - /// - protected bool module2_isInitialized; - - void InitializeModule2() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (module2_isInitialized) - return; - module2 = GetModule2_NoLock(); - module2_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - 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 => (TypeAttributes)attributes; - set => attributes = (int)value; - } - /// Attributes - protected int attributes; - - /// - /// From column TypeDef.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column TypeDef.Namespace - /// - public UTF8String Namespace { - get => @namespace; - set => @namespace = value; - } - /// Name - protected UTF8String @namespace; - - /// - /// From column TypeDef.Extends - /// - public ITypeDefOrRef BaseType { - get { - if (!baseType_isInitialized) - InitializeBaseType(); - return baseType; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - baseType = value; - baseType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected ITypeDefOrRef baseType; - /// - protected bool baseType_isInitialized; - - void InitializeBaseType() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (baseType_isInitialized) - return; - baseType = GetBaseType_NoLock(); - baseType_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual ITypeDefOrRef GetBaseType_NoLock() => null; - - /// Reset - protected void ResetBaseType() => baseType_isInitialized = false; - - /// - /// From column TypeDef.FieldList - /// - public IList Fields { - get { - if (fields is null) - InitializeFields(); - return fields; - } - } - /// - protected LazyList fields; - /// Initializes - protected virtual void InitializeFields() => - Interlocked.CompareExchange(ref fields, new LazyList(this), null); - - /// - /// From column TypeDef.MethodList - /// - public IList Methods { - get { - if (methods is null) - InitializeMethods(); - return methods; - } - } - /// - protected LazyList methods; - /// Initializes - protected virtual void InitializeMethods() => - Interlocked.CompareExchange(ref methods, new LazyList(this), null); - - /// - public IList GenericParameters { - get { - if (genericParameters is null) - InitializeGenericParameters(); - return genericParameters; - } - } - /// - protected LazyList genericParameters; - /// Initializes - protected virtual void InitializeGenericParameters() => - Interlocked.CompareExchange(ref genericParameters, new LazyList(this), null); - - /// - /// Gets the interfaces - /// - public IList Interfaces { - get { - if (interfaces is null) - InitializeInterfaces(); - return interfaces; - } - } - /// - protected IList interfaces; - /// Initializes - protected virtual void InitializeInterfaces() => - Interlocked.CompareExchange(ref interfaces, new List(), null); - - /// - public IList DeclSecurities { - get { - if (declSecurities is null) - InitializeDeclSecurities(); - return declSecurities; - } - } - /// - protected IList declSecurities; - /// Initializes - protected virtual void InitializeDeclSecurities() => - Interlocked.CompareExchange(ref declSecurities, new List(), null); - - /// - /// Gets/sets the class layout - /// - public ClassLayout ClassLayout { - get { - if (!classLayout_isInitialized) - InitializeClassLayout(); - return classLayout; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - classLayout = value; - classLayout_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected ClassLayout classLayout; - /// - protected bool classLayout_isInitialized; - - void InitializeClassLayout() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (classLayout_isInitialized) - return; - classLayout = GetClassLayout_NoLock(); - classLayout_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - ClassLayout GetOrCreateClassLayout() { - var cl = ClassLayout; - if (cl is not null) - return cl; - Interlocked.CompareExchange(ref classLayout, new ClassLayoutUser(0, 0), null); - return classLayout; - } - - /// Called to initialize - protected virtual ClassLayout GetClassLayout_NoLock() => null; - - /// - public bool HasDeclSecurities => DeclSecurities.Count > 0; - - /// - /// Gets/sets the enclosing type. It's null if this isn't a nested class. - /// - public TypeDef DeclaringType { - get { - if (!declaringType2_isInitialized) - InitializeDeclaringType2(); - return declaringType2; - } - set { - var currentDeclaringType = DeclaringType2; - if (currentDeclaringType == value) - return; - if (currentDeclaringType is not null) - currentDeclaringType.NestedTypes.Remove(this); // Will set DeclaringType2 = 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 - Module2 = null; - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType => DeclaringType; - - /// - /// Called by and should normally not be called by any user - /// code. Use instead. Only call this if you must set the - /// declaring type without inserting it in the declaring type's method list. - /// - public TypeDef DeclaringType2 { - get { - if (!declaringType2_isInitialized) - InitializeDeclaringType2(); - return declaringType2; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - declaringType2 = value; - declaringType2_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected TypeDef declaringType2; - /// - protected bool declaringType2_isInitialized; - - void InitializeDeclaringType2() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (declaringType2_isInitialized) - return; - declaringType2 = GetDeclaringType2_NoLock(); - declaringType2_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual TypeDef GetDeclaringType2_NoLock() => null; - - /// - /// Gets all the nested types - /// - public IList NestedTypes { - get { - if (nestedTypes is null) - InitializeNestedTypes(); - return nestedTypes; - } - } - /// - protected LazyList nestedTypes; - /// Initializes - protected virtual void InitializeNestedTypes() => - Interlocked.CompareExchange(ref nestedTypes, new LazyList(this), null); - - /// - /// Gets all events - /// - public IList Events { - get { - if (events is null) - InitializeEvents(); - return events; - } - } - /// - protected LazyList events; - /// Initializes - protected virtual void InitializeEvents() => - Interlocked.CompareExchange(ref events, new LazyList(this), null); - - /// - /// Gets all properties - /// - public IList Properties { - get { - if (properties is null) - InitializeProperties(); - return properties; - } - } - /// - protected LazyList properties; - /// Initializes - protected virtual void InitializeProperties() => - Interlocked.CompareExchange(ref properties, new LazyList(this), null); - - /// - /// 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 => 3; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// true if there's at least one in - /// - public bool HasFields => Fields.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasMethods => Methods.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasGenericParameters => GenericParameters.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasEvents => Events.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasProperties => Properties.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasNestedTypes => NestedTypes.Count > 0; - - /// - /// true if there's at least one in - /// - public bool HasInterfaces => Interfaces.Count > 0; - - /// - /// true if is not null - /// - public bool HasClassLayout => ClassLayout is not null; - - /// - /// Gets/sets the packing size. If you write to this property but - /// is null, it will be created. The value is returned - /// if is null. - /// - public ushort PackingSize { - get { - var cl = ClassLayout; - return cl is null ? ushort.MaxValue : cl.PackingSize; - } - set { - var cl = GetOrCreateClassLayout(); - cl.PackingSize = value; - } - } - - /// - /// Gets/sets the class size. If you write to this property but - /// is null, it will be created. The value is returned - /// if is null. - /// - public uint ClassSize { - get { - var cl = ClassLayout; - return cl is null ? uint.MaxValue : cl.ClassSize; - } - set { - var cl = GetOrCreateClassLayout(); - cl.ClassSize = value; - } - } - - /// - public bool IsValueType { - get { - // Don't include abstract since value types can be abstract without throwing at runtime - // 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 is null) - return false; - if (!baseType.DefinitionAssembly.IsCorLib()) - return false; - - // PERF: Don't allocate a System.String by calling FullName etc. - UTF8String baseName, baseNamespace; - if (baseType is TypeRef baseTr) { - baseName = baseTr.Name; - baseNamespace = baseTr.Namespace; - } - else { - var baseTd = baseType as TypeDef; - if (baseTd is null) - return false; - baseName = baseTd.Name; - baseNamespace = baseTd.Namespace; - } - - if (baseNamespace != systemString) - return false; - if (baseName != valueTypeString && baseName != enumString) - return false; - - 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 { - // Don't include abstract since value types can be abstract without throwing at runtime - // 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 is null) - return false; - if (!baseType.DefinitionAssembly.IsCorLib()) - return false; - - // PERF: Don't allocate a System.String by calling FullName etc. - if (baseType is TypeRef baseTr) - return baseTr.Namespace == systemString && baseTr.Name == enumString; - if (baseType is TypeDef baseTd) - return baseTd.Namespace == systemString && baseTd.Name == enumString; - return false; - } - } - - /// - /// true if it's a delegate (it derives from ) - /// - public bool IsDelegate { - get { - if ((Attributes & (TypeAttributes.Abstract | TypeAttributes.ClassSemanticsMask)) != TypeAttributes.Class) - return false; - var baseType = BaseType; - if (baseType is null) - return false; - if (!baseType.DefinitionAssembly.IsCorLib()) - return false; - - // PERF: Don't allocate a System.String by calling FullName etc. - if (baseType is TypeRef baseTr) - return baseTr.Namespace == systemString && baseTr.Name == multicastDelegateString; - if (baseType is TypeDef baseTd) - return baseTd.Namespace == systemString && baseTd.Name == multicastDelegateString; - return false; - } - } - - /// - /// true if this is a nested type (it has a declaring type) - /// - public bool IsNested => DeclaringType is not null; - - /// - public bool IsPrimitive => this.IsPrimitive(); - - /// - /// Checks whether this type has opted into equivalence - /// - public bool IsEquivalent => TIAHelper.IsTypeDefEquivalent(this); - - /// - /// Modify property: = - /// ( & ) | . - /// - /// Value to AND - /// Value to OR - void ModifyAttributes(TypeAttributes andMask, TypeAttributes orMask) => - attributes = (attributes & (int)andMask) | (int)orMask; - - /// - /// Set or clear flags in - /// - /// true if flags should be set, false if flags should - /// be cleared - /// Flags to set or clear - void ModifyAttributes(bool set, TypeAttributes flags) { - if (set) - attributes |= (int)flags; - else - attributes &= ~(int)flags; - } - - /// - /// Gets/sets the visibility - /// - public TypeAttributes Visibility { - get => (TypeAttributes)attributes & TypeAttributes.VisibilityMask; - set => ModifyAttributes(~TypeAttributes.VisibilityMask, value & TypeAttributes.VisibilityMask); - } - - /// - /// true if is set - /// - public bool IsNotPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NotPublic; - - /// - /// true if is set - /// - public bool IsPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.Public; - - /// - /// true if is set - /// - public bool IsNestedPublic => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPublic; - - /// - /// true if is set - /// - public bool IsNestedPrivate => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedPrivate; - - /// - /// true if is set - /// - public bool IsNestedFamily => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamily; - - /// - /// true if is set - /// - public bool IsNestedAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedAssembly; - - /// - /// true if is set - /// - public bool IsNestedFamilyAndAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamANDAssem; - - /// - /// true if is set - /// - public bool IsNestedFamilyOrAssembly => ((TypeAttributes)attributes & TypeAttributes.VisibilityMask) == TypeAttributes.NestedFamORAssem; - - /// - /// Gets/sets the layout - /// - public TypeAttributes Layout { - get => (TypeAttributes)attributes & TypeAttributes.LayoutMask; - set => ModifyAttributes(~TypeAttributes.LayoutMask, value & TypeAttributes.LayoutMask); - } - - /// - /// true if is set - /// - public bool IsAutoLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.AutoLayout; - - /// - /// true if is set - /// - public bool IsSequentialLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.SequentialLayout; - - /// - /// true if is set - /// - public bool IsExplicitLayout => ((TypeAttributes)attributes & TypeAttributes.LayoutMask) == TypeAttributes.ExplicitLayout; - - /// - /// Gets/sets the bit - /// - public bool IsInterface { - get => ((TypeAttributes)attributes & TypeAttributes.Interface) != 0; - set => ModifyAttributes(value, TypeAttributes.Interface); - } - - /// - /// Gets/sets the bit - /// - public bool IsClass { - get => ((TypeAttributes)attributes & TypeAttributes.Interface) == 0; - set => ModifyAttributes(!value, TypeAttributes.Interface); - } - - /// - /// Gets/sets the bit - /// - public bool IsAbstract { - get => ((TypeAttributes)attributes & TypeAttributes.Abstract) != 0; - set => ModifyAttributes(value, TypeAttributes.Abstract); - } - - /// - /// Gets/sets the bit - /// - public bool IsSealed { - get => ((TypeAttributes)attributes & TypeAttributes.Sealed) != 0; - set => ModifyAttributes(value, TypeAttributes.Sealed); - } - - /// - /// Gets/sets the bit - /// - public bool IsSpecialName { - get => ((TypeAttributes)attributes & TypeAttributes.SpecialName) != 0; - set => ModifyAttributes(value, TypeAttributes.SpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool IsImport { - get => ((TypeAttributes)attributes & TypeAttributes.Import) != 0; - set => ModifyAttributes(value, TypeAttributes.Import); - } - - /// - /// Gets/sets the bit - /// - public bool IsSerializable { - get => ((TypeAttributes)attributes & TypeAttributes.Serializable) != 0; - set => ModifyAttributes(value, TypeAttributes.Serializable); - } - - /// - /// Gets/sets the bit - /// - public bool IsWindowsRuntime { - get => ((TypeAttributes)attributes & TypeAttributes.WindowsRuntime) != 0; - set => ModifyAttributes(value, TypeAttributes.WindowsRuntime); - } - - /// - /// Gets/sets the string format - /// - public TypeAttributes StringFormat { - get => (TypeAttributes)attributes & TypeAttributes.StringFormatMask; - set => ModifyAttributes(~TypeAttributes.StringFormatMask, value & TypeAttributes.StringFormatMask); - } - - /// - /// true if is set - /// - public bool IsAnsiClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AnsiClass; - - /// - /// true if is set - /// - public bool IsUnicodeClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.UnicodeClass; - - /// - /// true if is set - /// - public bool IsAutoClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.AutoClass; - - /// - /// true if is set - /// - public bool IsCustomFormatClass => ((TypeAttributes)attributes & TypeAttributes.StringFormatMask) == TypeAttributes.CustomFormatClass; - - /// - /// Gets/sets the bit - /// - public bool IsBeforeFieldInit { - get => ((TypeAttributes)attributes & TypeAttributes.BeforeFieldInit) != 0; - set => ModifyAttributes(value, TypeAttributes.BeforeFieldInit); - } - - /// - /// Gets/sets the bit - /// - public bool IsForwarder { - get => ((TypeAttributes)attributes & TypeAttributes.Forwarder) != 0; - set => ModifyAttributes(value, TypeAttributes.Forwarder); - } - - /// - /// Gets/sets the bit - /// - public bool IsRuntimeSpecialName { - get => ((TypeAttributes)attributes & TypeAttributes.RTSpecialName) != 0; - set => ModifyAttributes(value, TypeAttributes.RTSpecialName); - } - - /// - /// Gets/sets the bit - /// - public bool HasSecurity { - get => ((TypeAttributes)attributes & TypeAttributes.HasSecurity) != 0; - set => ModifyAttributes(value, TypeAttributes.HasSecurity); - } - - /// - /// true if this is the global (aka. <Module>) type - /// - public bool IsGlobalModuleType { - get { - var mod = Module; - return mod is not null && mod.GlobalType == this; - } - } - - /// - /// Gets a list of all nested types and all their nested types - /// - public IEnumerable GetTypes() => AllTypesHelper.Types(NestedTypes); - - /// - /// Gets an enum's underlying type or null if none. Should only be called - /// if this is an enum. - /// - public TypeSig GetEnumUnderlyingType() { - 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 is not null) - return fieldSig.Type; - } - } - return null; - } - - /// - /// Resolves a method or a field. (owner type) is ignored when - /// resolving the method/field. Private scope methods/fields are not returned. - /// - /// A method/field reference - /// A or a instance or null - /// if it couldn't be resolved. - public IMemberForwarded Resolve(MemberRef memberRef) => Resolve(memberRef, 0); - - /// - /// Resolves a method or a field. (owner type) is ignored when - /// resolving the method/field. - /// - /// A method/field reference - /// Method/field signature comparison options - /// A or a instance or null - /// if it couldn't be resolved. - public IMemberForwarded Resolve(MemberRef memberRef, SigComparerOptions options) { - if (memberRef is null) - return null; - - var methodSig = memberRef.MethodSig; - if (methodSig is not null) - return FindMethodCheckBaseType(memberRef.Name, methodSig, options, memberRef.Module); - - var fieldSig = memberRef.FieldSig; - if (fieldSig is not null) - return FindFieldCheckBaseType(memberRef.Name, fieldSig, options, memberRef.Module); - - return null; - } - - /// - /// Finds a method. Private scope methods are not returned. - /// - /// Method name - /// Method signature - /// The first method that matches or null if none found - public MethodDef FindMethod(UTF8String name, MethodSig sig) => FindMethod(name, sig, 0, null); - - /// - /// Finds a method - /// - /// Method name - /// 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) => FindMethod(name, sig, options, null); - - /// - /// Finds a method - /// - /// Method name - /// Method signature - /// Method signature comparison 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 is null) - return null; - var comparer = new SigComparer(options, sourceModule); - bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeMethodIsComparable) != 0; - var methods = Methods; - int count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (!allowPrivateScope && method.IsPrivateScope && sourceModule != Module) - continue; - if (!UTF8String.Equals(method.Name, name)) - continue; - if (comparer.Equals(method.MethodSig, sig)) - return method; - } - return null; - } - - /// - /// Finds a method by name - /// - /// Name of method - /// The or null if not found - public MethodDef FindMethod(UTF8String name) { - 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; - } - return null; - } - - /// - /// Finds all methods by name - /// - /// Name of method - /// All methods with that name - public IEnumerable FindMethods(UTF8String name) { - 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; - } - } - - /// - /// Finds the class constructor (aka type initializer). It's the method named .cctor - /// - /// The class constructor or null if none found - public MethodDef FindStaticConstructor() { - var methods = Methods; - int count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method.IsStaticConstructor) - return method; - } - return null; - } - - /// - /// Finds the class constructor (aka type initializer). It's the method named .cctor. - /// If it doesn't exist, it is created, inserted into and returned. - /// The created .cctor will have just one RET instruction. - /// - /// The class constructor - public MethodDef FindOrCreateStaticConstructor() { - var cctor = FindStaticConstructor(); - if (cctor is not null) - return cctor; - - var implFlags = MethodImplAttributes.IL | MethodImplAttributes.Managed; - var flags = MethodAttributes.Private | MethodAttributes.Static | - MethodAttributes.HideBySig | MethodAttributes.ReuseSlot | - MethodAttributes.SpecialName | MethodAttributes.RTSpecialName; - var module = Module; - cctor = module.UpdateRowId(new MethodDefUser(MethodDef.StaticConstructorName, - MethodSig.CreateStatic(module.CorLibTypes.Void), implFlags, flags)); - var body = new CilBody(); - body.InitLocals = true; - body.MaxStack = 8; - body.Instructions.Add(OpCodes.Ret.ToInstruction()); - cctor.Body = body; - Methods.Add(cctor); - return cctor; - } - - /// - /// Finds all instance constructors (not class constructors) - /// - /// All instance constructors - public IEnumerable FindInstanceConstructors() { - var methods = Methods; - int count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method.IsInstanceConstructor) - yield return method; - } - } - - /// - /// Finds all static and instance constructors - /// - /// All static and instance constructors - public IEnumerable FindConstructors() { - var methods = Methods; - int count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method.IsConstructor) - yield return method; - } - } - - /// - /// Finds the default instance constructor (the one with no arguments) - /// - /// The default instance constructor or null if none - public MethodDef FindDefaultConstructor() { - 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; - if (sig is not null && sig.Params.Count == 0) - return method; - } - return null; - } - - /// - /// Finds a field. Private scope fields are not returned. - /// - /// Field name - /// Field signature - /// The first field that matches or null if none found - public FieldDef FindField(UTF8String name, FieldSig sig) => FindField(name, sig, 0, null); - - /// - /// Finds a field - /// - /// Field name - /// 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) => FindField(name, sig, options, null); - - /// - /// Finds a field - /// - /// Field name - /// Field signature - /// Field signature comparison options - /// 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 is null) - return null; - var comparer = new SigComparer(options, sourceModule); - bool allowPrivateScope = (options & SigComparerOptions.PrivateScopeFieldIsComparable) != 0; - var fields = Fields; - int count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (!allowPrivateScope && field.IsPrivateScope && sourceModule != Module) - continue; - if (!UTF8String.Equals(field.Name, name)) - continue; - if (comparer.Equals(field.FieldSig, sig)) - return field; - } - return null; - } - - /// - /// Finds a field by name - /// - /// Name of field - /// The or null if not found - public FieldDef FindField(UTF8String name) { - 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; - } - return null; - } - - /// - /// Finds all fields by name - /// - /// Name of field - /// All fields with that name - public IEnumerable FindFields(UTF8String name) { - 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; - } - } - - /// - /// Finds an event - /// - /// Name of event - /// Type of event - /// A or null if not found - public EventDef FindEvent(UTF8String name, IType type) => FindEvent(name, type, 0, null); - - /// - /// Finds an event - /// - /// Name of event - /// Type of event - /// Event type comparison options - /// A or null if not found - public EventDef FindEvent(UTF8String name, IType type, SigComparerOptions options) => FindEvent(name, type, options, null); - - /// - /// Finds an event - /// - /// Name of event - /// Type of event - /// Event type comparison options - /// 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 is null) - return null; - var comparer = new SigComparer(options, sourceModule); - 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)) - return @event; - } - return null; - } - - /// - /// Finds an event by name - /// - /// Name of event - /// The or null if not found - public EventDef FindEvent(UTF8String name) { - 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; - } - return null; - } - - /// - /// Finds all events by name - /// - /// Name of event - /// All events with that name - public IEnumerable FindEvents(UTF8String name) { - 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; - } - } - - /// - /// Finds a property - /// - /// Name of property - /// Property signature - /// A or null if not found - public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig) => FindProperty(name, propSig, 0, null); - - /// - /// Finds a property - /// - /// Name of property - /// Property signature - /// Property signature comparison options - /// A or null if not found - public PropertyDef FindProperty(UTF8String name, CallingConventionSig propSig, SigComparerOptions options) => FindProperty(name, propSig, options, null); - - /// - /// Finds a property - /// - /// Name of property - /// Property signature - /// Property signature comparison options - /// 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 is null) - return null; - var comparer = new SigComparer(options, sourceModule); - 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)) - return prop; - } - return null; - } - - /// - /// Finds a prop by name - /// - /// Name of prop - /// The or null if not found - public PropertyDef FindProperty(UTF8String name) { - 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; - } - return null; - } - - /// - /// Finds all props by name - /// - /// Name of prop - /// All props with that name - public IEnumerable FindProperties(UTF8String name) { - 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; - } - } - - /// - /// Finds a method by checking this type or any of its base types - /// - /// Method name - /// Method signature - /// The method or null if it wasn't found - 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 - /// - /// Method name - /// Method signature - /// Method signature comparison options - /// The method or null if it wasn't found - 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 - /// - /// Method name - /// Method signature - /// Method signature comparison options - /// The module that needs to find the method or null - /// 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 not null) { - var md = td.FindMethod(name, sig, options, sourceModule); - if (md is not null) - return md; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds a method by checking this type or any of its base types - /// - /// Method name - /// The method or null if it wasn't found - public MethodDef FindMethodCheckBaseType(UTF8String name) { - var td = this; - while (td is not null) { - var md = td.FindMethod(name); - if (md is not null) - return md; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds a field by checking this type or any of its base types - /// - /// Field name - /// Field signature - /// The field or null if it wasn't found - 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 - /// - /// Field name - /// Field signature - /// Field signature comparison options - /// The field or null if it wasn't found - 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 - /// - /// Field name - /// Field signature - /// Field signature comparison options - /// The module that needs to find the field or null - /// 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 not null) { - var fd = td.FindField(name, sig, options, sourceModule); - if (fd is not null) - return fd; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds a field by checking this type or any of its base types - /// - /// Field name - /// The field or null if it wasn't found - public FieldDef FindFieldCheckBaseType(UTF8String name) { - var td = this; - while (td is not null) { - var fd = td.FindField(name); - if (fd is not null) - return fd; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds an event by checking this type or any of its base types - /// - /// Event name - /// Event type - /// The event or null if it wasn't found - public EventDef FindEventCheckBaseType(UTF8String name, ITypeDefOrRef eventType) { - var td = this; - while (td is not null) { - var ed = td.FindEvent(name, eventType); - if (ed is not null) - return ed; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds an event by checking this type or any of its base types - /// - /// Event name - /// The event or null if it wasn't found - public EventDef FindEventCheckBaseType(UTF8String name) { - var td = this; - while (td is not null) { - var ed = td.FindEvent(name); - if (ed is not null) - return ed; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds a property by checking this type or any of its base types - /// - /// Property name - /// Property signature - /// The property or null if it wasn't found - 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 - /// - /// 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) => 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 is not null) { - var pd = td.FindProperty(name, sig, options, sourceModule); - if (pd is not null) - return pd; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// Finds a property by checking this type or any of its base types - /// - /// Property name - /// The property or null if it wasn't found - public PropertyDef FindPropertyCheckBaseType(UTF8String name) { - var td = this; - while (td is not null) { - var pd = td.FindProperty(name); - if (pd is not null) - return pd; - td = td.BaseType.ResolveTypeDef(); - } - return null; - } - - /// - /// 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); - - /// - /// Removes a method from this type. It also removes it from any properties and events. - /// - /// The method to remove - /// true if we should remove all - /// empty properties and events. - public void Remove(MethodDef method, bool removeEmptyPropertiesEvents) { - if (method is null) - return; - - 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); - } - - 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) - evt.RemoveMethod = null; - if (evt.InvokeMethod == method) - evt.InvokeMethod = null; - evt.OtherMethods.Remove(method); - } - - if (removeEmptyPropertiesEvents) { - RemoveEmptyProperties(); - RemoveEmptyEvents(); - } - - Methods.Remove(method); - } - - void RemoveEmptyProperties() { - var properties = Properties; - for (int i = properties.Count - 1; i >= 0; i--) { - if (properties[i].IsEmpty) - properties.RemoveAt(i); - } - } - - void RemoveEmptyEvents() { - var events = Events; - for (int i = events.Count - 1; i >= 0; i--) { - if (events[i].IsEmpty) - events.RemoveAt(i); - } - } - - /// - void IListListener.OnLazyAdd(int index, ref FieldDef value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref FieldDef value) { -#if DEBUG - if (value.DeclaringType != this) - throw new InvalidOperationException("Added field's DeclaringType != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, FieldDef value) { - if (value.DeclaringType is not null) - throw new InvalidOperationException("Field is already owned by another type. Set DeclaringType to null first."); - value.DeclaringType2 = this; - } - - /// - void IListListener.OnRemove(int index, FieldDef value) => value.DeclaringType2 = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var field in fields.GetEnumerable_NoLock()) - field.DeclaringType2 = null; - } - - /// - void IListListener.OnLazyAdd(int index, ref MethodDef value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref MethodDef value) { -#if DEBUG - if (value.DeclaringType != this) - throw new InvalidOperationException("Added method's DeclaringType != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, MethodDef value) { - 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); - } - - /// - void IListListener.OnRemove(int index, MethodDef value) { - value.DeclaringType2 = null; - value.Parameters.UpdateThisParameterType(null); - } - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var method in methods.GetEnumerable_NoLock()) { - method.DeclaringType2 = null; - method.Parameters.UpdateThisParameterType(null); - } - } - - /// - void IListListener.OnLazyAdd(int index, ref TypeDef value) { -#if DEBUG - 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 - } - - /// - void IListListener.OnAdd(int index, TypeDef value) { - 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 not null) - throw new InvalidOperationException("Type is already owned by another module. Remove it from that module's type list."); - value.DeclaringType2 = this; - } - - /// - void IListListener.OnRemove(int index, TypeDef value) { - value.DeclaringType2 = null; - value.Module2 = null; - } - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var type in nestedTypes.GetEnumerable_NoLock()) - type.DeclaringType2 = null; - } - - /// - void IListListener.OnLazyAdd(int index, ref EventDef value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref EventDef value) { -#if DEBUG - if (value.DeclaringType != this) - throw new InvalidOperationException("Added event's DeclaringType != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, EventDef value) { - if (value.DeclaringType is not null) - throw new InvalidOperationException("Event is already owned by another type. Set DeclaringType to null first."); - value.DeclaringType2 = this; - } - - /// - void IListListener.OnRemove(int index, EventDef value) => value.DeclaringType2 = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var @event in events.GetEnumerable_NoLock()) - @event.DeclaringType2 = null; - } - - /// - void IListListener.OnLazyAdd(int index, ref PropertyDef value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref PropertyDef value) { -#if DEBUG - if (value.DeclaringType != this) - throw new InvalidOperationException("Added property's DeclaringType != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, PropertyDef value) { - if (value.DeclaringType is not null) - throw new InvalidOperationException("Property is already owned by another type. Set DeclaringType to null first."); - value.DeclaringType2 = this; - } - - /// - void IListListener.OnRemove(int index, PropertyDef value) => value.DeclaringType2 = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var prop in properties.GetEnumerable_NoLock()) - prop.DeclaringType2 = null; - } - - /// - void IListListener.OnLazyAdd(int index, ref GenericParam value) => OnLazyAdd2(index, ref value); - - internal virtual void OnLazyAdd2(int index, ref GenericParam value) { -#if DEBUG - if (value.Owner != this) - throw new InvalidOperationException("Added generic param's Owner != this"); -#endif - } - - /// - void IListListener.OnAdd(int index, GenericParam value) { - 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; - } - - /// - void IListListener.OnRemove(int index, GenericParam value) => value.Owner = null; - - /// - void IListListener.OnResize(int index) { - } - - /// - void IListListener.OnClear() { - foreach (var gp in genericParameters.GetEnumerable_NoLock()) - gp.Owner = null; - } - - /// - /// Gets all fields named - /// - /// Field name - /// A list of 0 or more fields with name - public IList GetFields(UTF8String name) { - 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) - result.Add(field); - } - return result; - } - - /// - /// Gets the first field named - /// - /// Field name - /// The field or null if none found - public FieldDef GetField(UTF8String name) { - var fields = Fields; - int count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (field.Name == name) - return field; - } - return null; - } - - internal static bool GetClassSize(TypeDef td, out uint size) { - size = 0; - if (td is null) - return false; - if (!td.IsValueType) - return false; // Not supported by us - if (!td.IsSequentialLayout && !td.IsExplicitLayout) { - if (td.Fields.Count != 1) - return false; - var fd = td.Fields[0]; - if (fd is null) - return false; - return fd.GetFieldSize(out size); - } - - var classLayout = td.ClassLayout; - if (classLayout is null) - return false; - uint classSize = classLayout.ClassSize; - if (classSize != 0) { - size = classSize; - return true; - } - - // Not supported by us - return false; - } - - /// - /// FInd a method implementation method - /// - /// Method - /// - protected MethodDef FindMethodImplMethod(IMethodDefOrRef mdr) { - // Check common case first - if (mdr is MethodDef md) - return md; - - // Must be a member ref - var mr = mdr as MemberRef; - 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 is not 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 is null) - break; - - var gis = ts.TypeSig as GenericInstSig; - if (gis is null || gis.GenericType is null) - return null; - parent = gis.GenericType.TypeDefOrRef; - } - - var td = parent as TypeDef; - 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 is not null) - td = Module.Find(tr); - } - if (td is null) - return null; - return td.FindMethod(mr.Name, mr.MethodSig); - } - - /// - public override string ToString() => FullName; - } - - /// - /// A TypeDef row created by the user and not present in the original .NET file - /// - public class TypeDefUser : TypeDef { - /// - /// Constructor - /// - /// Name - public TypeDefUser(UTF8String name) - : this(null, name, null) { - } - - /// - /// Constructor - /// - /// Namespace - /// Name - public TypeDefUser(UTF8String @namespace, UTF8String name) - : this(@namespace, name, null) { - } - - /// - /// Constructor - /// - /// Name - /// Base class or null if it's an interface - public TypeDefUser(UTF8String name, ITypeDefOrRef baseType) - : this(null, name, baseType) { - } - - /// - /// Constructor - /// - /// Namespace - /// Name - /// Base class or null if it's an interface - public TypeDefUser(UTF8String @namespace, UTF8String name, ITypeDefOrRef baseType) { - 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; - baseType_isInitialized = true; - } - } - - /// - /// Created from a row in the TypeDef table - /// - 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; - - /// - public uint OrigRid => origRid; - - /// - protected override ITypeDefOrRef GetBaseType_NoLock() => readerModule.ResolveTypeDefOrRef(extendsCodedToken, new GenericParamContext(this)); - - /// - protected override void InitializeFields() { - var list = readerModule.Metadata.GetFieldRidList(origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveField(list2[index])); - Interlocked.CompareExchange(ref fields, tmp, null); - } - - /// - protected override void InitializeMethods() { - var list = readerModule.Metadata.GetMethodRidList(origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveMethod(list2[index])); - Interlocked.CompareExchange(ref methods, tmp, null); - } - - /// - protected override void InitializeGenericParameters() { - var list = readerModule.Metadata.GetGenericParamRidList(Table.TypeDef, origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveGenericParam(list2[index])); - Interlocked.CompareExchange(ref genericParameters, tmp, null); - } - - /// - protected override void InitializeInterfaces() { - var list = readerModule.Metadata.GetInterfaceImplRidList(origRid); - var tmp = new LazyList(list.Count, list, (list2, index) => readerModule.ResolveInterfaceImpl(list2[index], new GenericParamContext(this))); - Interlocked.CompareExchange(ref interfaces, tmp, null); - } - - /// - protected override void InitializeDeclSecurities() { - var list = readerModule.Metadata.GetDeclSecurityRidList(Table.TypeDef, origRid); - var tmp = new LazyList(list.Count, list, (list2, index) => readerModule.ResolveDeclSecurity(list2[index])); - Interlocked.CompareExchange(ref declSecurities, tmp, null); - } - - /// - protected override ClassLayout GetClassLayout_NoLock() => readerModule.ResolveClassLayout(readerModule.Metadata.GetClassLayoutRid(origRid)); - - /// - protected override TypeDef GetDeclaringType2_NoLock() { - if (!readerModule.TablesStream.TryReadNestedClassRow(readerModule.Metadata.GetNestedClassRid(origRid), out var row)) - return null; - return readerModule.ResolveTypeDef(row.EnclosingClass); - } - - TypeDef DeclaringType2_NoLock { - get { - if (!declaringType2_isInitialized) { - declaringType2 = GetDeclaringType2_NoLock(); - declaringType2_isInitialized = true; - } - return declaringType2; - } - } - - /// - protected override void InitializeEvents() { - var mapRid = readerModule.Metadata.GetEventMapRid(origRid); - var list = readerModule.Metadata.GetEventRidList(mapRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveEvent(list2[index])); - Interlocked.CompareExchange(ref events, tmp, null); - } - - /// - protected override void InitializeProperties() { - var mapRid = readerModule.Metadata.GetPropertyMapRid(origRid); - var list = readerModule.Metadata.GetPropertyRidList(mapRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveProperty(list2[index])); - Interlocked.CompareExchange(ref properties, tmp, null); - } - - /// - protected override void InitializeNestedTypes() { - var list = readerModule.Metadata.GetNestedClassRidList(origRid); - var tmp = new LazyList(list.Count, this, list, (list2, index) => readerModule.ResolveTypeDef(list2[index])); - Interlocked.CompareExchange(ref nestedTypes, tmp, null); - } - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.TypeDef, 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(this), list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - /// - protected override ModuleDef GetModule2_NoLock() => DeclaringType2_NoLock is not null ? null : readerModule; - - /// - /// Constructor - /// - /// The module which contains this TypeDef row - /// Row ID - /// If is null - /// If is invalid - public TypeDefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.TypeDefTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"TypeDef rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - bool b = readerModule.TablesStream.TryReadTypeDefRow(origRid, out var row); - Debug.Assert(b); - extendsCodedToken = row.Extends; - attributes = (int)row.Flags; - name = readerModule.StringsStream.ReadNoNull(row.Name); - @namespace = readerModule.StringsStream.ReadNoNull(row.Namespace); - } - - /// - /// Gets all methods overrides - /// - /// The method - /// Generic parameter context - /// A list (possibly empty) of all methods overrides - internal IList GetMethodOverrides(MethodDefMD method, GenericParamContext gpContext) { - if (method is null) - return new List(); - - if (methodRidToOverrides is null) - InitializeMethodOverrides(); - - if (methodRidToOverrides.TryGetValue(method.OrigRid, out var overrides)) { - var newList = new List(overrides.Count); - - for (int i = 0; i < overrides.Count; i++) { - var ovr = overrides[i]; - var newMethodBody = (IMethodDefOrRef)readerModule.ResolveToken(ovr.MethodBodyToken, gpContext); - var newMethodDeclaration = (IMethodDefOrRef)readerModule.ResolveToken(ovr.MethodDeclarationToken, gpContext); - newList.Add(new MethodOverride(newMethodBody, newMethodDeclaration)); - } - return newList; - } - return new List(); - } - - readonly struct MethodOverrideTokens { - public readonly uint MethodBodyToken; - public readonly uint MethodDeclarationToken; - - public MethodOverrideTokens(uint methodBodyToken, uint methodDeclarationToken) { - MethodBodyToken = methodBodyToken; - MethodDeclarationToken = methodDeclarationToken; - } - } - - void InitializeMethodOverrides() { - var newMethodRidToOverrides = new Dictionary>(); - - var ridList = readerModule.Metadata.GetMethodImplRidList(origRid); - for (int i = 0; i < ridList.Count; i++) { - if (!readerModule.TablesStream.TryReadMethodImplRow(ridList[i], out var row)) - continue; - - var methodBody = readerModule.ResolveMethodDefOrRef(row.MethodBody); - var methodDecl = readerModule.ResolveMethodDefOrRef(row.MethodDeclaration); - 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 is null || method.DeclaringType != this) - continue; - - uint rid = method.Rid; - if (!newMethodRidToOverrides.TryGetValue(rid, out var overrides)) - newMethodRidToOverrides[rid] = overrides = new List(); - overrides.Add(new MethodOverrideTokens(methodBody.MDToken.Raw, methodDecl.MDToken.Raw)); - } - Interlocked.CompareExchange(ref methodRidToOverrides, newMethodRidToOverrides, null); - } - - /// - /// Initializes all . Only those s - /// that are property or event handlers get updated. - /// - internal void InitializeMethodSemanticsAttributes() { - var mapRid = readerModule.Metadata.GetPropertyMapRid(origRid); - var list = readerModule.Metadata.GetPropertyRidList(mapRid); - for (int i = 0; i < list.Count; i++) { - var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Property, list[i]); - for (int j = 0; j < ridList.Count; j++) { - if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[j], out var row)) - continue; - var method = readerModule.ResolveMethod(row.Method); - if (method is null) - continue; - - Interlocked.CompareExchange(ref method.semAttrs, row.Semantic | MethodDef.SEMATTRS_INITD, 0); - } - } - - mapRid = readerModule.Metadata.GetEventMapRid(origRid); - list = readerModule.Metadata.GetEventRidList(mapRid); - for (int i = 0; i < list.Count; i++) { - var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Event, list[i]); - for (int j = 0; j < ridList.Count; j++) { - if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[j], out var row)) - continue; - var method = readerModule.ResolveMethod(row.Method); - if (method is null) - continue; - - Interlocked.CompareExchange(ref method.semAttrs, row.Semantic | MethodDef.SEMATTRS_INITD, 0); - } - } - } - - /// - /// Initializes a property's special methods - /// - /// The property - /// Updated with a list of all get methods - /// Updated with a list of all set methods - /// Updated with a list of all other methods - internal void InitializeProperty(PropertyDefMD prop, out IList getMethods, out IList setMethods, out IList otherMethods) { - getMethods = new List(); - setMethods = new List(); - otherMethods = new List(); - if (prop is null) - return; - - var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Property, prop.OrigRid); - for (int i = 0; i < ridList.Count; i++) { - if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[i], out var row)) - continue; - var method = readerModule.ResolveMethod(row.Method); - if (method is null || method.DeclaringType != prop.DeclaringType) - continue; - - // It's documented to be flags, but ignore those with more than one bit set - switch ((MethodSemanticsAttributes)row.Semantic) { - case MethodSemanticsAttributes.Setter: - if (!setMethods.Contains(method)) - setMethods.Add(method); - break; - - case MethodSemanticsAttributes.Getter: - if (!getMethods.Contains(method)) - getMethods.Add(method); - break; - - case MethodSemanticsAttributes.Other: - if (!otherMethods.Contains(method)) - otherMethods.Add(method); - break; - - default: - // Ignore anything else - break; - } - } - } - - /// - /// Initializes an event's special methods - /// - /// The event - /// Updated with the addOn method or null if none - /// Updated with the fire method or null if none - /// Updated with the removeOn method or null if none - /// Updated with a list of all other methods - internal void InitializeEvent(EventDefMD evt, out MethodDef addMethod, out MethodDef invokeMethod, out MethodDef removeMethod, out IList otherMethods) { - addMethod = null; - invokeMethod = null; - removeMethod = null; - otherMethods = new List(); - if (evt is null) - return; - - var ridList = readerModule.Metadata.GetMethodSemanticsRidList(Table.Event, evt.OrigRid); - for (int i = 0; i < ridList.Count; i++) { - if (!readerModule.TablesStream.TryReadMethodSemanticsRow(ridList[i], out var row)) - continue; - var method = readerModule.ResolveMethod(row.Method); - 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 is null) - addMethod = method; - break; - - case MethodSemanticsAttributes.RemoveOn: - if (removeMethod is null) - removeMethod = method; - break; - - case MethodSemanticsAttributes.Fire: - if (invokeMethod is null) - invokeMethod = method; - break; - - case MethodSemanticsAttributes.Other: - if (!otherMethods.Contains(method)) - otherMethods.Add(method); - break; - - default: - // Ignore anything else - break; - } - } - } - - /// - internal override void OnLazyAdd2(int index, ref FieldDef value) { - if (value.DeclaringType != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadField(value.Rid).InitializeAll()); - value.DeclaringType2 = this; - } - } - - /// - internal override void OnLazyAdd2(int index, ref MethodDef value) { - if (value.DeclaringType != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadMethod(value.Rid).InitializeAll()); - value.DeclaringType2 = this; - value.Parameters.UpdateThisParameterType(this); - } - } - - /// - internal override void OnLazyAdd2(int index, ref EventDef value) { - if (value.DeclaringType != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadEvent(value.Rid).InitializeAll()); - value.DeclaringType2 = this; - } - } - - /// - internal override void OnLazyAdd2(int index, ref PropertyDef value) { - if (value.DeclaringType != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadProperty(value.Rid).InitializeAll()); - value.DeclaringType2 = this; - } - } - - /// - internal override void OnLazyAdd2(int index, ref GenericParam value) { - if (value.Owner != this) { - // More than one owner... This module has invalid metadata. - value = readerModule.ForceUpdateRowId(readerModule.ReadGenericParam(value.Rid).InitializeAll()); - value.Owner = this; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeDefFinder.cs b/Plugins/dnlib/DotNet/TypeDefFinder.cs deleted file mode 100644 index bfd5600..0000000 --- a/Plugins/dnlib/DotNet/TypeDefFinder.cs +++ /dev/null @@ -1,279 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Text; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// Finds s - /// - sealed class TypeDefFinder : ITypeDefFinder, IDisposable { - const SigComparerOptions TypeComparerOptions = SigComparerOptions.DontCompareTypeScope | SigComparerOptions.TypeRefCanReferenceGlobalType; - bool isCacheEnabled; - readonly bool includeNestedTypes; - 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 - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// true if the cache is enabled. false if the cache - /// is disabled and a slower O(n) lookup is performed. - /// - public bool IsCacheEnabled { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return IsCacheEnabled_NoLock; -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - IsCacheEnabled_NoLock = value; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - - bool IsCacheEnabled_NoLock { - get => isCacheEnabled; - set { - if (isCacheEnabled == value) - return; - - if (typeEnumerator is not null) { - typeEnumerator.Dispose(); - typeEnumerator = null; - } - - typeRefCache.Clear(); - normalNameCache.Clear(); - reflectionNameCache.Clear(); - - if (value) - InitializeTypeEnumerator(); - - isCacheEnabled = value; - } - } - - /// - /// Constructor - /// - /// All root types. All their nested types are also included. - /// If is null - public TypeDefFinder(IEnumerable rootTypes) - : this(rootTypes, true) { - } - - /// - /// Constructor - /// - /// All root types - /// true if all nested types that are reachable - /// from should also be included. - /// If is null - public TypeDefFinder(IEnumerable rootTypes, bool includeNestedTypes) { - this.rootTypes = rootTypes ?? throw new ArgumentNullException(nameof(rootTypes)); - this.includeNestedTypes = includeNestedTypes; - } - - void InitializeTypeEnumerator() { - if (typeEnumerator is not null) { - typeEnumerator.Dispose(); - typeEnumerator = null; - } - typeEnumerator = (includeNestedTypes ? AllTypesHelper.Types(rootTypes) : rootTypes).GetEnumerator(); - } - - /// - /// Resets the cache (clears all cached elements). Use this method if the cache is - /// enabled but some of the types have been modified (eg. removed, added, renamed). - /// - public void ResetCache() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - bool old = IsCacheEnabled_NoLock; - IsCacheEnabled_NoLock = false; - IsCacheEnabled_NoLock = old; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - public TypeDef Find(string fullName, bool isReflectionName) { - if (fullName is null) - return null; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (isCacheEnabled) - return isReflectionName ? FindCacheReflection(fullName) : FindCacheNormal(fullName); - return isReflectionName ? FindSlowReflection(fullName) : FindSlowNormal(fullName); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// - public TypeDef Find(TypeRef typeRef) { - if (typeRef is null) - return null; -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return isCacheEnabled ? FindCache(typeRef) : FindSlow(typeRef); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - TypeDef FindCache(TypeRef typeRef) { - if (typeRefCache.TryGetValue(typeRef, out var cachedType)) - return cachedType; - - // Build the cache lazily - var comparer = new SigComparer(TypeComparerOptions); - while (true) { - cachedType = GetNextTypeDefCache(); - if (cachedType is null || comparer.Equals(cachedType, typeRef)) - return cachedType; - } - } - - TypeDef FindCacheReflection(string fullName) { - if (reflectionNameCache.TryGetValue(fullName, out var cachedType)) - return cachedType; - - // Build the cache lazily - while (true) { - cachedType = GetNextTypeDefCache(); - if (cachedType is null) - return cachedType; - sb.Length = 0; - if (FullNameFactory.FullName(cachedType, true, null, sb) == fullName) - return cachedType; - } - } - - TypeDef FindCacheNormal(string fullName) { - if (normalNameCache.TryGetValue(fullName, out var cachedType)) - return cachedType; - - // Build the cache lazily - while (true) { - cachedType = GetNextTypeDefCache(); - if (cachedType is null) - return cachedType; - sb.Length = 0; - if (FullNameFactory.FullName(cachedType, false, null, sb) == fullName) - return cachedType; - } - } - - TypeDef FindSlow(TypeRef typeRef) { - InitializeTypeEnumerator(); - var comparer = new SigComparer(TypeComparerOptions); - while (true) { - var type = GetNextTypeDef(); - if (type is null || comparer.Equals(type, typeRef)) - return type; - } - } - - TypeDef FindSlowReflection(string fullName) { - InitializeTypeEnumerator(); - while (true) { - var type = GetNextTypeDef(); - if (type is null) - return type; - sb.Length = 0; - if (FullNameFactory.FullName(type, true, null, sb) == fullName) - return type; - } - } - - TypeDef FindSlowNormal(string fullName) { - InitializeTypeEnumerator(); - while (true) { - var type = GetNextTypeDef(); - if (type is null) - return type; - sb.Length = 0; - if (FullNameFactory.FullName(type, false, null, sb) == fullName) - return type; - } - } - - /// - /// Gets the next or null if there are no more left - /// - /// The next or null if none - TypeDef GetNextTypeDef() { - while (typeEnumerator.MoveNext()) { - var type = typeEnumerator.Current; - if (type is not null) - return type; - } - return null; - } - - /// - /// Gets the next or null if there are no more left. - /// The cache is updated with the returned before the method - /// returns. - /// - /// The next or null if none - TypeDef GetNextTypeDefCache() { - var type = GetNextTypeDef(); - if (type is null) - return null; - - // Only insert it if another type with the exact same sig/name isn't already - // in the cache. This should only happen with some obfuscated assemblies. - - if (!typeRefCache.ContainsKey(type)) - typeRefCache[type] = type; - string fn; - sb.Length = 0; - if (!normalNameCache.ContainsKey(fn = FullNameFactory.FullName(type, false, null, sb))) - normalNameCache[fn] = type; - sb.Length = 0; - if (!reflectionNameCache.ContainsKey(fn = FullNameFactory.FullName(type, true, null, sb))) - reflectionNameCache[fn] = type; - - return type; - } - - /// - public void Dispose() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (typeEnumerator is not null) - typeEnumerator.Dispose(); - typeEnumerator = null; - typeRefCache = null; - normalNameCache = null; - reflectionNameCache = null; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeHelper.cs b/Plugins/dnlib/DotNet/TypeHelper.cs deleted file mode 100644 index ddfe4d4..0000000 --- a/Plugins/dnlib/DotNet/TypeHelper.cs +++ /dev/null @@ -1,351 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet { - /// - /// Various helper methods for classes to prevent infinite recursion - /// - struct TypeHelper { - RecursionCounter recursionCounter; - - 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) => ms is not null && ContainsGenericParameter(ms.GenericInstMethodSig); - - internal static bool ContainsGenericParameter(MemberRef mr) { - if (mr is null) - return false; - - if (ContainsGenericParameter(mr.Signature)) - return true; - - var cl = mr.Class; - - if (cl is ITypeDefOrRef tdr) - return tdr.ContainsGenericParameter; - - if (cl is MethodDef md) - return TypeHelper.ContainsGenericParameter(md.Signature); - - return false; - } - - /// - /// Checks whether contains a or a - /// . - /// - /// Calling convention signature - /// true if contains a - /// or a . - public static bool ContainsGenericParameter(CallingConventionSig callConv) { - if (callConv is FieldSig fs) - return ContainsGenericParameter(fs); - - if (callConv is MethodBaseSig mbs) - return ContainsGenericParameter(mbs); - - if (callConv is LocalSig ls) - return ContainsGenericParameter(ls); - - if (callConv is GenericInstMethodSig gim) - return ContainsGenericParameter(gim); - - return false; - } - - /// - /// Checks whether contains a or a - /// . - /// - /// Field signature - /// true if contains a - /// or a . - public static bool ContainsGenericParameter(FieldSig fieldSig) => new TypeHelper().ContainsGenericParameterInternal(fieldSig); - - /// - /// Checks whether contains a or a - /// . - /// - /// Method or property signature - /// true if contains a - /// or a . - public static bool ContainsGenericParameter(MethodBaseSig methodSig) => new TypeHelper().ContainsGenericParameterInternal(methodSig); - - /// - /// Checks whether contains a or a - /// . - /// - /// Local signature - /// true if contains a - /// or a . - public static bool ContainsGenericParameter(LocalSig localSig) => new TypeHelper().ContainsGenericParameterInternal(localSig); - - /// - /// Checks whether contains a or a - /// . - /// - /// Generic method signature - /// true if contains a - /// or a . - public static bool ContainsGenericParameter(GenericInstMethodSig gim) => new TypeHelper().ContainsGenericParameterInternal(gim); - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(IType type) { - if (type is TypeDef td) - return ContainsGenericParameter(td); - - if (type is TypeRef tr) - return ContainsGenericParameter(tr); - - if (type is TypeSpec ts) - return ContainsGenericParameter(ts); - - if (type is TypeSig sig) - return ContainsGenericParameter(sig); - - if (type is ExportedType et) - return ContainsGenericParameter(et); - - return false; - } - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(TypeDef type) => new TypeHelper().ContainsGenericParameterInternal(type); - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(TypeRef type) => new TypeHelper().ContainsGenericParameterInternal(type); - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(TypeSpec type) => new TypeHelper().ContainsGenericParameterInternal(type); - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(TypeSig type) => new TypeHelper().ContainsGenericParameterInternal(type); - - /// - /// Checks whether contains a or a - /// . - /// - /// Type - /// true if contains a or a - /// . - public static bool ContainsGenericParameter(ExportedType type) => new TypeHelper().ContainsGenericParameterInternal(type); - - bool ContainsGenericParameterInternal(TypeDef type) => false; - - bool ContainsGenericParameterInternal(TypeRef type) => false; - - bool ContainsGenericParameterInternal(TypeSpec type) { - if (type is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = ContainsGenericParameterInternal(type.TypeSig); - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameterInternal(ITypeDefOrRef tdr) { - if (tdr is null) - return false; - // TypeDef and TypeRef contain no generic parameters - return ContainsGenericParameterInternal(tdr as TypeSpec); - } - - bool ContainsGenericParameterInternal(TypeSig type) { - if (type is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res; - switch (type.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.ValueType: - case ElementType.Class: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - res = ContainsGenericParameterInternal((type as TypeDefOrRefSig).TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - res = true; - break; - - case ElementType.FnPtr: - res = ContainsGenericParameterInternal((type as FnPtrSig).Signature); - break; - - case ElementType.GenericInst: - var gi = (GenericInstSig)type; - res = ContainsGenericParameterInternal(gi.GenericType) || - ContainsGenericParameter(gi.GenericArguments); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Array: - case ElementType.SZArray: - case ElementType.Pinned: - case ElementType.ValueArray: - case ElementType.Module: - res = ContainsGenericParameterInternal((type as NonLeafSig).Next); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - res = ContainsGenericParameterInternal((type as ModifierSig).Modifier) || - ContainsGenericParameterInternal((type as NonLeafSig).Next); - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - case ElementType.Sentinel: - default: - res = false; - break; - } - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameterInternal(ExportedType type) => false; - - bool ContainsGenericParameterInternal(CallingConventionSig callConv) { - if (callConv is FieldSig fs) - return ContainsGenericParameterInternal(fs); - - if (callConv is MethodBaseSig mbs) - return ContainsGenericParameterInternal(mbs); - - if (callConv is LocalSig ls) - return ContainsGenericParameterInternal(ls); - - if (callConv is GenericInstMethodSig gim) - return ContainsGenericParameterInternal(gim); - - return false; - } - - bool ContainsGenericParameterInternal(FieldSig fs) { - if (fs is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = ContainsGenericParameterInternal(fs.Type); - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameterInternal(MethodBaseSig mbs) { - if (mbs is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = ContainsGenericParameterInternal(mbs.RetType) || - ContainsGenericParameter(mbs.Params) || - ContainsGenericParameter(mbs.ParamsAfterSentinel); - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameterInternal(LocalSig ls) { - if (ls is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = ContainsGenericParameter(ls.Locals); - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameterInternal(GenericInstMethodSig gim) { - if (gim is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = ContainsGenericParameter(gim.GenericArguments); - - recursionCounter.Decrement(); - return res; - } - - bool ContainsGenericParameter(IList types) { - if (types is null) - return false; - if (!recursionCounter.Increment()) - return false; - - bool res = false; - int count = types.Count; - for (int i = 0; i < count; i++) { - var type = types[i]; - if (ContainsGenericParameter(type)) { - res = true; - break; - } - } - recursionCounter.Decrement(); - return res; - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeNameParser.cs b/Plugins/dnlib/DotNet/TypeNameParser.cs deleted file mode 100644 index 30c2fa3..0000000 --- a/Plugins/dnlib/DotNet/TypeNameParser.cs +++ /dev/null @@ -1,855 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.Serialization; -using System.Text; - -namespace dnlib.DotNet { - /// - /// Thrown by when it fails to parse a type name - /// - [Serializable] - public class TypeNameParserException : Exception { - /// - /// Default constructor - /// - public TypeNameParserException() { - } - - /// - /// Constructor - /// - /// Exception message - public TypeNameParserException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Exception message - /// Inner exception or null if none - public TypeNameParserException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected TypeNameParserException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// Helps create types - /// - public interface IAssemblyRefFinder { - /// - /// Finds a 's when the original assembly - /// info is missing from the full type name. - /// - /// A non-nested - /// 's or null - AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef); - } - - /// - /// Parses a type name and creates an - /// - public abstract class TypeNameParser : IDisposable { - /// Owner module - protected ModuleDef ownerModule; - readonly GenericParamContext gpContext; - StringReader reader; - readonly IAssemblyRefFinder typeNameParserHelper; - RecursionCounter recursionCounter; - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// A new instance - /// If parsing failed - public static ITypeDefOrRef ParseReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => - ParseReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - /// A new instance - /// If parsing failed - public static ITypeDefOrRef ParseReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { - using (var parser = new ReflectionTypeNameParser(ownerModule, typeFullName, typeNameParserHelper, gpContext)) - return parser.Parse(); - } - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// A new instance or null if parsing failed - public static ITypeDefOrRef ParseReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => - ParseReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - /// A new instance or null if parsing failed - public static ITypeDefOrRef ParseReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { - try { - return ParseReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, gpContext); - } - catch (TypeNameParserException) { - return null; - } - } - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// A new instance - /// If parsing failed - public static TypeSig ParseAsTypeSigReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => - ParseAsTypeSigReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - /// A new instance - /// If parsing failed - public static TypeSig ParseAsTypeSigReflectionThrow(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { - using (var parser = new ReflectionTypeNameParser(ownerModule, typeFullName, typeNameParserHelper, gpContext)) - return parser.ParseAsTypeSig(); - } - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// A new instance or null if parsing failed - public static TypeSig ParseAsTypeSigReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) => - ParseAsTypeSigReflection(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()); - - /// - /// Parses a Reflection type name and creates a - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - /// A new instance or null if parsing failed - public static TypeSig ParseAsTypeSigReflection(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { - try { - return ParseAsTypeSigReflectionThrow(ownerModule, typeFullName, typeNameParserHelper, gpContext); - } - catch (TypeNameParserException) { - return null; - } - } - - /// - /// Constructor - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - protected TypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) - : this(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()) { - } - - /// - /// Constructor - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - protected TypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) { - this.ownerModule = ownerModule; - reader = new StringReader(typeFullName ?? string.Empty); - this.typeNameParserHelper = typeNameParserHelper; - this.gpContext = gpContext; - } - - /// - /// Parses a type name and creates a - /// - /// A new instance - /// If parsing failed - internal ITypeDefOrRef Parse() => ownerModule.UpdateRowId(ParseAsTypeSig().ToTypeDefOrRef()); - - /// - /// Parses a type name and creates a - /// - /// A new instance - /// If parsing failed - internal abstract TypeSig ParseAsTypeSig(); - - /// - /// Increment recursion counter - /// - /// If this method has been called too many times - protected void RecursionIncrement() { - if (!recursionCounter.Increment()) - throw new TypeNameParserException("Stack overflow"); - } - - /// - /// Decrement recursion counter - /// - protected void RecursionDecrement() => recursionCounter.Decrement(); - - /// - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose method - /// - /// true if called by - protected virtual void Dispose(bool disposing) { - if (!disposing) - return; - if (reader is not null) - reader.Dispose(); - reader = null; - } - - internal abstract class TSpec { - public readonly ElementType etype; - - protected TSpec(ElementType etype) => this.etype = etype; - } - - internal sealed class SZArraySpec : TSpec { - public static readonly SZArraySpec Instance = new SZArraySpec(); - SZArraySpec() - : base(ElementType.SZArray) { - } - } - - internal sealed class ArraySpec : TSpec { - public uint rank; - public readonly IList sizes = new List(); - public readonly IList lowerBounds = new List(); - - public ArraySpec() - : base(ElementType.Array) { - } - } - - internal sealed class GenericInstSpec : TSpec { - public readonly List args = new List(); - - public GenericInstSpec() - : base(ElementType.GenericInst) { - } - } - - internal sealed class ByRefSpec : TSpec { - public static readonly ByRefSpec Instance = new ByRefSpec(); - ByRefSpec() - : base(ElementType.ByRef) { - } - } - - internal sealed class PtrSpec : TSpec { - public static readonly PtrSpec Instance = new PtrSpec(); - PtrSpec() - : base(ElementType.Ptr) { - } - } - - internal GenericSig ReadGenericSig() { - Verify(ReadChar() == '!', "Expected '!'"); - if (PeekChar() == '!') { - ReadChar(); - return new GenericMVar(ReadUInt32(), gpContext.Method); - } - return new GenericVar(ReadUInt32(), gpContext.Type); - } - - internal TypeSig CreateTypeSig(IList tspecs, TypeSig currentSig) { - 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); - break; - - case ElementType.Array: - var arraySpec = (ArraySpec)tspec; - currentSig = new ArraySig(currentSig, arraySpec.rank, arraySpec.sizes, arraySpec.lowerBounds); - break; - - case ElementType.GenericInst: - var ginstSpec = (GenericInstSpec)tspec; - currentSig = new GenericInstSig(currentSig as ClassOrValueTypeSig, ginstSpec.args); - break; - - case ElementType.ByRef: - currentSig = new ByRefSig(currentSig); - break; - - case ElementType.Ptr: - currentSig = new PtrSig(currentSig); - break; - - default: - Verify(false, "Unknown TSpec"); - break; - } - } - return currentSig; - } - - /// - /// Reads a including any possible nested s. - /// - /// Character separating nested types - /// A new instance, which could be nested. - protected TypeRef ReadTypeRefAndNestedNoAssembly(char nestedChar) { - var typeRef = ReadTypeRefNoAssembly(); - while (true) { - SkipWhite(); - if (PeekChar() != nestedChar) - break; - ReadChar(); - var newTypeRef = ReadTypeRefNoAssembly(); - newTypeRef.ResolutionScope = typeRef; - typeRef = newTypeRef; - } - return typeRef; - } - - /// - /// Reads a namespace and name and creates a TypeRef. Does not read any nested types. - /// - /// A new instance - 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, false), out var ns, out var name); - return ownerModule.UpdateRowId(new TypeRefUser(ownerModule, ns, name)); - } - - static void GetNamespaceAndName(string fullName, out string ns, out string name) { - int index = fullName.LastIndexOf('.'); - if (index < 0) { - ns = string.Empty; - name = fullName; - } - else { - ns = fullName.Substring(0, index); - name = fullName.Substring(index + 1); - } - } - - internal TypeSig ToTypeSig(ITypeDefOrRef type) { - if (type is TypeDef td) - return ToTypeSig(td, td.IsValueType); - if (type is TypeRef tr) - return ToTypeSig(tr, IsValueType(tr)); - if (type is TypeSpec ts) - return ts.TypeSig; - Verify(false, "Unknown type"); - return null; - } - - static TypeSig ToTypeSig(ITypeDefOrRef type, bool isValueType) => isValueType ? (TypeSig)new ValueTypeSig(type) : new ClassSig(type); - - internal AssemblyRef FindAssemblyRef(TypeRef nonNestedTypeRef) { - AssemblyRef asmRef = null; - if (nonNestedTypeRef is not null && typeNameParserHelper is not null) - asmRef = typeNameParserHelper.FindAssemblyRef(nonNestedTypeRef); - if (asmRef is not null) - return asmRef; - var ownerAsm = ownerModule.Assembly; - if (ownerAsm is not null) - return ownerModule.UpdateRowId(ownerAsm.ToAssemblyRef()); - return AssemblyRef.CurrentAssembly; - } - - internal bool IsValueType(TypeRef typeRef) => typeRef is not null && typeRef.IsValueType; - - internal static void Verify(bool b, string msg) { - if (!b) - throw new TypeNameParserException(msg); - } - - internal void SkipWhite() { - while (true) { - int next = PeekChar(); - if (next == -1) - break; - if (!char.IsWhiteSpace((char)next)) - break; - ReadChar(); - } - } - - internal uint ReadUInt32() { - SkipWhite(); - bool readInt = false; - uint val = 0; - while (true) { - int c = PeekChar(); - if (c == -1 || !(c >= '0' && c <= '9')) - break; - ReadChar(); - uint newVal = val * 10 + (uint)(c - '0'); - Verify(newVal >= val, "Integer overflow"); - val = newVal; - readInt = true; - } - Verify(readInt, "Expected an integer"); - return val; - } - - internal int ReadInt32() { - SkipWhite(); - - bool isSigned = false; - if (PeekChar() == '-') { - isSigned = true; - ReadChar(); - } - - uint val = ReadUInt32(); - if (isSigned) { - Verify(val <= (uint)int.MaxValue + 1, "Integer overflow"); - return -(int)val; - } - else { - Verify(val <= (uint)int.MaxValue, "Integer overflow"); - return (int)val; - } - } - - internal string ReadId() => ReadId(true, true); - - internal string ReadId(bool ignoreWhiteSpace, bool ignoreEqualSign) { - SkipWhite(); - var sb = new StringBuilder(); - int c; - while ((c = GetIdChar(ignoreWhiteSpace, ignoreEqualSign)) != -1) - sb.Append((char)c); - Verify(sb.Length > 0, "Expected an id"); - return sb.ToString(); - } - - /// - /// Peeks the next char. -1 if no more chars. - /// - protected int PeekChar() => reader.Peek(); - - /// - /// Gets the next char or -1 if no more chars - /// - protected int ReadChar() => reader.Read(); - - /// - /// Gets the next ID char or -1 if no more ID chars - /// - /// true if white space should be ignored - /// true if equal sign '=' should be ignored - internal abstract int GetIdChar(bool ignoreWhiteSpace, bool ignoreEqualSign); - } - - /// - /// Parses reflection type names. Grammar http://msdn.microsoft.com/en-us/library/yfsftwz6.aspx - /// - sealed class ReflectionTypeNameParser : TypeNameParser { - /// - /// Constructor - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - public ReflectionTypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper) - : base(ownerModule, typeFullName, typeNameParserHelper, new GenericParamContext()) { - } - - /// - /// Constructor - /// - /// Module that will own the returned or null - /// Full name of type - /// Helper class - /// Generic parameter context - public ReflectionTypeNameParser(ModuleDef ownerModule, string typeFullName, IAssemblyRefFinder typeNameParserHelper, GenericParamContext gpContext) - : base(ownerModule, typeFullName, typeNameParserHelper, gpContext) { - } - - /// - /// Parses an assembly name - /// - /// Full assembly name - /// A new instance or null if parsing failed - public static AssemblyRef ParseAssemblyRef(string asmFullName) => ParseAssemblyRef(asmFullName, new GenericParamContext()); - - /// - /// Parses an assembly name - /// - /// Full assembly name - /// Generic parameter context - /// A new instance or null if parsing failed - public static AssemblyRef ParseAssemblyRef(string asmFullName, GenericParamContext gpContext) { - try { - using (var parser = new ReflectionTypeNameParser(null, asmFullName, null, gpContext)) - return parser.ReadAssemblyRef(); - } - catch { - return null; - } - } - - /// - internal override TypeSig ParseAsTypeSig() { - try { - var type = ReadType(true); - SkipWhite(); - Verify(PeekChar() == -1, "Extra input after type name"); - return type; - } - catch (TypeNameParserException) { - throw; - } - catch (Exception ex) { - throw new TypeNameParserException("Could not parse type name", ex); - } - } - - TypeSig ReadType(bool readAssemblyReference) { - RecursionIncrement(); - TypeSig result; - - SkipWhite(); - if (PeekChar() == '!') { - var currentSig = ReadGenericSig(); - var tspecs = ReadTSpecs(); - ReadOptionalAssemblyRef(); - result = CreateTypeSig(tspecs, currentSig); - } - else { - var typeRef = ReadTypeRefAndNestedNoAssembly('+'); - var tspecs = ReadTSpecs(); - var nonNestedTypeRef = TypeRef.GetNonNestedTypeRef(typeRef); - AssemblyRef asmRef; - if (readAssemblyReference) - asmRef = ReadOptionalAssemblyRef() ?? FindAssemblyRef(nonNestedTypeRef); - else - asmRef = FindAssemblyRef(nonNestedTypeRef); - nonNestedTypeRef.ResolutionScope = asmRef; - - // Make sure the CorLib types are used whenever possible - result = null; - if (typeRef == nonNestedTypeRef) { - var corLibSig = ownerModule.CorLibTypes.GetCorLibTypeSig(typeRef.Namespace, typeRef.Name, typeRef.DefinitionAssembly); - if (corLibSig is not null) - result = corLibSig; - } - if (result is null) { - var typeDef = Resolve(asmRef, typeRef); - result = ToTypeSig(typeDef is not null ? (ITypeDefOrRef)typeDef : typeRef); - } - - if (tspecs.Count != 0) - result = CreateTypeSig(tspecs, result); - } - - RecursionDecrement(); - return result; - } - - TypeDef Resolve(AssemblyRef asmRef, TypeRef typeRef) { - var asm = ownerModule.Assembly; - 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 is not null && td.Module == ownerModule ? td : null; - } - - AssemblyRef ReadOptionalAssemblyRef() { - SkipWhite(); - if (PeekChar() == ',') { - ReadChar(); - return ReadAssemblyRef(); - } - return null; - } - - IList ReadTSpecs() { - var tspecs = new List(); - while (true) { - SkipWhite(); - switch (PeekChar()) { - case '[': // SZArray, Array, or GenericInst - ReadChar(); - SkipWhite(); - var peeked = PeekChar(); - if (peeked == ']') { - // SZ array - Verify(ReadChar() == ']', "Expected ']'"); - tspecs.Add(SZArraySpec.Instance); - } - else if (peeked == '*' || peeked == ',' || peeked == '-' || char.IsDigit((char)peeked)) { - // Array - - var arraySpec = new ArraySpec(); - arraySpec.rank = 0; - while (true) { - SkipWhite(); - int c = PeekChar(); - if (c == '*') - ReadChar(); - else if (c == ',' || c == ']') { - } - else if (c == '-' || char.IsDigit((char)c)) { - int lower = ReadInt32(); - uint? size; - SkipWhite(); - Verify(ReadChar() == '.', "Expected '.'"); - Verify(ReadChar() == '.', "Expected '.'"); - if (PeekChar() == '.') { - ReadChar(); - size = null; - } - else { - SkipWhite(); - if (PeekChar() == '-') { - int upper = ReadInt32(); - Verify(upper >= lower, "upper < lower"); - size = (uint)(upper - lower + 1); - Verify(size.Value != 0 && size.Value <= 0x1FFFFFFF, "Invalid size"); - } - else { - uint upper = ReadUInt32(); - long lsize = (long)upper - (long)lower + 1; - Verify(lsize > 0 && lsize <= 0x1FFFFFFF, "Invalid size"); - size = (uint)lsize; - } - } - if (arraySpec.lowerBounds.Count == arraySpec.rank) - arraySpec.lowerBounds.Add(lower); - if (size.HasValue && arraySpec.sizes.Count == arraySpec.rank) - arraySpec.sizes.Add(size.Value); - } - else - Verify(false, "Unknown char"); - - arraySpec.rank++; - SkipWhite(); - if (PeekChar() != ',') - break; - ReadChar(); - } - - Verify(ReadChar() == ']', "Expected ']'"); - tspecs.Add(arraySpec); - } - else { - // Generic args - - var ginstSpec = new GenericInstSpec(); - while (true) { - SkipWhite(); - peeked = PeekChar(); - bool needSeperators = peeked == '['; - if (peeked == ']') - break; - Verify(!needSeperators || ReadChar() == '[', "Expected '['"); - ginstSpec.args.Add(ReadType(needSeperators)); - SkipWhite(); - Verify(!needSeperators || ReadChar() == ']', "Expected ']'"); - SkipWhite(); - if (PeekChar() != ',') - break; - ReadChar(); - } - - Verify(ReadChar() == ']', "Expected ']'"); - tspecs.Add(ginstSpec); - } - break; - - case '&': // ByRef - ReadChar(); - tspecs.Add(ByRefSpec.Instance); - break; - - case '*': // Ptr - ReadChar(); - tspecs.Add(PtrSpec.Instance); - break; - - default: - return tspecs; - } - } - } - - AssemblyRef ReadAssemblyRef() { - var asmRef = new AssemblyRefUser(); - if (ownerModule is not null) - ownerModule.UpdateRowId(asmRef); - - asmRef.Name = ReadAssemblyNameId(); - SkipWhite(); - if (PeekChar() != ',') - return asmRef; - ReadChar(); - - while (true) { - SkipWhite(); - int c = PeekChar(); - if (c == -1 || c == ']') - break; - if (c == ',') { - ReadChar(); - continue; - } - - string key = ReadId(); - SkipWhite(); - if (PeekChar() != '=') - continue; - ReadChar(); - string value = ReadId(); - - switch (key.ToUpperInvariant()) { - case "VERSION": - asmRef.Version = Utils.ParseVersion(value); - break; - - case "CONTENTTYPE": - if (value.Equals("WindowsRuntime", StringComparison.OrdinalIgnoreCase)) - asmRef.ContentType = AssemblyAttributes.ContentType_WindowsRuntime; - else - asmRef.ContentType = AssemblyAttributes.ContentType_Default; - break; - - case "RETARGETABLE": - if (value.Equals("Yes", StringComparison.OrdinalIgnoreCase)) - asmRef.IsRetargetable = true; - else - asmRef.IsRetargetable = false; - break; - - case "PUBLICKEY": - if (value.Equals("null", StringComparison.OrdinalIgnoreCase) || - value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) - asmRef.PublicKeyOrToken = new PublicKey(); - else - asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKey(Utils.ParseBytes(value)); - asmRef.Attributes |= AssemblyAttributes.PublicKey; - break; - - case "PUBLICKEYTOKEN": - if (value.Equals("null", StringComparison.OrdinalIgnoreCase) || - value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) - asmRef.PublicKeyOrToken = new PublicKeyToken(); - else - asmRef.PublicKeyOrToken = PublicKeyBase.CreatePublicKeyToken(Utils.ParseBytes(value)); - asmRef.Attributes &= ~AssemblyAttributes.PublicKey; - break; - - case "CULTURE": - case "LANGUAGE": - if (value.Equals("neutral", StringComparison.OrdinalIgnoreCase)) - asmRef.Culture = UTF8String.Empty; - else - asmRef.Culture = value; - break; - } - } - - return asmRef; - } - - string ReadAssemblyNameId() { - SkipWhite(); - var sb = new StringBuilder(); - int c; - while ((c = GetAsmNameChar()) != -1) - sb.Append((char)c); - var name = sb.ToString().Trim(); - Verify(name.Length > 0, "Expected an assembly name"); - return name; - } - - int GetAsmNameChar() { - int c = PeekChar(); - if (c == -1) - return -1; - switch (c) { - case '\\': - ReadChar(); - return ReadChar(); - - case ']': - case ',': - return -1; - - default: - return ReadChar(); - } - } - - internal override int GetIdChar(bool ignoreWhiteSpace, bool ignoreEqualSign) { - int c = PeekChar(); - if (c == -1) - return -1; - if (ignoreWhiteSpace && char.IsWhiteSpace((char)c)) - return -1; - switch (c) { - case '\\': - ReadChar(); - return ReadChar(); - - case ',': - case '+': - case '&': - case '*': - case '[': - case ']': - case '=' when ignoreEqualSign: - return -1; - - default: - return ReadChar(); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeRef.cs b/Plugins/dnlib/DotNet/TypeRef.cs deleted file mode 100644 index bfaa511..0000000 --- a/Plugins/dnlib/DotNet/TypeRef.cs +++ /dev/null @@ -1,386 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the TypeRef table - /// - public abstract class TypeRef : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation, IResolutionScope { - /// - /// The row id in its table - /// - protected uint rid; - - /// - /// The owner module - /// - protected ModuleDef module; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.TypeRef, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int TypeDefOrRefTag => 1; - - /// - public int HasCustomAttributeTag => 2; - - /// - public int MemberRefParentTag => 1; - - /// - public int ResolutionScopeTag => 3; - - /// - int IGenericParameterProvider.NumberOfGenericParameters => 0; - - /// - string IType.TypeName => Name; - - /// - public string ReflectionName => FullNameFactory.Name(this, true, null); - - /// - string IType.Namespace => Namespace; - - /// - public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); - - /// - public string FullName => FullNameFactory.FullName(this, false, null, null); - - /// - public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); - - /// - public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); - - /// - public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); - - /// - public IScope Scope => FullNameFactory.Scope(this); - - /// - public ITypeDefOrRef ScopeType => this; - - /// - /// Always returns false since a does not contain any - /// or . - /// - public bool ContainsGenericParameter => false; - - /// - public ModuleDef Module => module; - - /// - /// From column TypeRef.ResolutionScope - /// - public IResolutionScope ResolutionScope { - get { - if (!resolutionScope_isInitialized) - InitializeResolutionScope(); - return resolutionScope; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - resolutionScope = value; - resolutionScope_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - protected IResolutionScope resolutionScope; - /// - protected bool resolutionScope_isInitialized; - - void InitializeResolutionScope() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (resolutionScope_isInitialized) - return; - resolutionScope = GetResolutionScope_NoLock(); - resolutionScope_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual IResolutionScope GetResolutionScope_NoLock() => null; - - /// - /// From column TypeRef.Name - /// - public UTF8String Name { - get => name; - set => name = value; - } - /// Name - protected UTF8String name; - - /// - /// From column TypeRef.Namespace - /// - public UTF8String Namespace { - get => @namespace; - set => @namespace = value; - } - /// Name - protected UTF8String @namespace; - - /// - /// 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 => 2; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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); - - /// - /// true if it's nested within another - /// - public bool IsNested => DeclaringType is not null; - - /// - public bool IsValueType { - get { - var td = Resolve(); - return td is not null && td.IsValueType; - } - } - - /// - public bool IsPrimitive => this.IsPrimitive(); - - /// - /// Gets the declaring type, if any - /// - public TypeRef DeclaringType => ResolutionScope as TypeRef; - - /// - 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() => Resolve(null); - - /// - /// Resolves the type - /// - /// 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 is null) - return null; - return module.Context.Resolver.Resolve(this, sourceModule ?? module); - } - - /// - /// Resolves the type - /// - /// A instance - /// If the type couldn't be resolved - public TypeDef ResolveThrow() => ResolveThrow(null); - - /// - /// Resolves the type - /// - /// The module that needs to resolve the type or null - /// A instance - /// If the type couldn't be resolved - public TypeDef ResolveThrow(ModuleDef sourceModule) { - var type = Resolve(sourceModule); - if (type is not null) - return type; - throw new TypeResolveException($"Could not resolve type: {this} ({DefinitionAssembly})"); - } - - /// - /// Gets the top-most (non-nested) - /// - /// Input - /// The non-nested or null - internal static TypeRef GetNonNestedTypeRef(TypeRef typeRef) { - if (typeRef is null) - return null; - for (int i = 0; i < 1000; i++) { - var next = typeRef.ResolutionScope as TypeRef; - if (next is null) - return typeRef; - typeRef = next; - } - return null; // Here if eg. the TypeRef has an infinite loop - } - - /// - public override string ToString() => FullName; - } - - /// - /// A TypeRef row created by the user and not present in the original .NET file - /// - public class TypeRefUser : TypeRef { - /// - /// Constructor - /// - /// Owner module - /// Type name - public TypeRefUser(ModuleDef module, UTF8String name) - : this(module, UTF8String.Empty, name) { - } - - /// - /// Constructor - /// - /// Owner module - /// Type namespace - /// Type name - public TypeRefUser(ModuleDef module, UTF8String @namespace, UTF8String name) - : this(module, @namespace, name, null) { - } - - /// - /// Constructor - /// - /// Owner module - /// Type namespace - /// Type name - /// Resolution scope (a , - /// , or ) - public TypeRefUser(ModuleDef module, UTF8String @namespace, UTF8String name, IResolutionScope resolutionScope) { - this.module = module; - this.resolutionScope = resolutionScope; - resolutionScope_isInitialized = true; - this.name = name; - this.@namespace = @namespace; - } - } - - /// - /// Created from a row in the TypeRef table - /// - sealed class TypeRefMD : TypeRef, IMDTokenProviderMD { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly uint resolutionScopeCodedToken; - - /// - public uint OrigRid => origRid; - - /// - protected override IResolutionScope GetResolutionScope_NoLock() => readerModule.ResolveResolutionScope(resolutionScopeCodedToken); - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.TypeRef, 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); - } - - /// - /// Constructor - /// - /// The module which contains this TypeRef row - /// Row ID - /// If is null - /// If is invalid - public TypeRefMD(ModuleDefMD readerModule, uint rid) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.TypeRefTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"TypeRef rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - module = readerModule; - bool b = readerModule.TablesStream.TryReadTypeRefRow(origRid, out var row); - Debug.Assert(b); - name = readerModule.StringsStream.ReadNoNull(row.Name); - @namespace = readerModule.StringsStream.ReadNoNull(row.Namespace); - resolutionScopeCodedToken = row.ResolutionScope; - } - } -} diff --git a/Plugins/dnlib/DotNet/TypeSig.cs b/Plugins/dnlib/DotNet/TypeSig.cs deleted file mode 100644 index 2132725..0000000 --- a/Plugins/dnlib/DotNet/TypeSig.cs +++ /dev/null @@ -1,1251 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.MD; - -/* -All TypeSig classes: - -TypeSig base class - LeafSig base class for leaf types - TypeDefOrRefSig contains a ITypeDefOrRef instance - CorLibTypeSig simple corlib types (eg. System.Int32) - ClassOrValueTypeSig base class for Class/ValueType element types - ValueTypeSig ValueType - ClassSig Class - GenericSig base class for generic vars - GenericVar Generic type parameter - GenericMVar Generic method parameter - SentinelSig Sentinel - FnPtrSig Function pointer sig - GenericInstSig Generic instance type (contains a generic type + all generic args) - NonLeafSig base class for non-leaf types - PtrSig Pointer - ByRefSig By ref - ArraySigBase Array base class - ArraySig Array - SZArraySig Single dimension, zero lower limit array (i.e., THETYPE[]) - ModifierSig C modifier base class - CModReqdSig C required modifier - CModOptSig C optional modifier - PinnedSig Pinned - ValueArraySig Value array (undocumented/not implemented by the CLR so don't use it) - ModuleSig Module (undocumented/not implemented by the CLR so don't use it) -*/ - -namespace dnlib.DotNet { - /// - /// Type sig base class - /// - public abstract class TypeSig : IType { - uint rid; - - /// - /// Returns the wrapped element type. Can only be null if it was an invalid sig or - /// if it's a - /// - public abstract TypeSig Next { get; } - - /// - /// Gets the element type - /// - public abstract ElementType ElementType { get; } - - /// - public MDToken MDToken => new MDToken(Table.TypeSpec, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - bool IIsTypeOrMethod.IsMethod => false; - - /// - bool IIsTypeOrMethod.IsType => true; - - /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { - var type = this.RemovePinnedAndModifiers() as GenericInstSig; - return type is null ? 0 : type.GenericArguments.Count; - } - } - - /// - public bool IsValueType { - get { - var t = this.RemovePinnedAndModifiers(); - if (t is null) - return false; - if (t.ElementType == ElementType.GenericInst) { - var gis = (GenericInstSig)t; - t = gis.GenericType; - if (t is null) - return false; - } - return t.ElementType.IsValueType(); - } - } - - /// - public bool IsPrimitive => ElementType.IsPrimitive(); - - /// - public string TypeName => FullNameFactory.Name(this, false, null); - - /// - UTF8String IFullName.Name { - get => new UTF8String(FullNameFactory.Name(this, false, null)); - set => throw new NotSupportedException(); - } - - /// - public string ReflectionName => FullNameFactory.Name(this, true, null); - - /// - public string Namespace => FullNameFactory.Namespace(this, false, null); - - /// - public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); - - /// - public string FullName => FullNameFactory.FullName(this, false, null, null, null, null); - - /// - public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null, null, null); - - /// - public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); - - /// - public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); - - /// - public IScope Scope => FullNameFactory.Scope(this); - - /// - public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); - - /// - public ModuleDef Module => FullNameFactory.OwnerModule(this); - - /// - /// true if it's a - /// - public bool IsTypeDefOrRef => this is TypeDefOrRefSig; - - /// - /// true if it's a - /// - public bool IsCorLibType => this is CorLibTypeSig; - - /// - /// true if it's a - /// - public bool IsClassSig => this is ClassSig; - - /// - /// true if it's a - /// - public bool IsValueTypeSig => this is ValueTypeSig; - - /// - /// true if it's a - /// - public bool IsGenericParameter => this is GenericSig; - - /// - /// true if it's a - /// - public bool IsGenericTypeParameter => this is GenericVar; - - /// - /// true if it's a - /// - public bool IsGenericMethodParameter => this is GenericMVar; - - /// - /// true if it's a - /// - public bool IsSentinel => this is SentinelSig; - - /// - /// true if it's a - /// - public bool IsFunctionPointer => this is FnPtrSig; - - /// - /// true if it's a - /// - public bool IsGenericInstanceType => this is GenericInstSig; - - /// - /// true if it's a - /// - public bool IsPointer => this is PtrSig; - - /// - /// true if it's a - /// - public bool IsByRef => this is ByRefSig; - - /// - /// true if it's a or a - /// - public bool IsSingleOrMultiDimensionalArray => this is ArraySigBase; - - /// - /// true if it's a - /// - public bool IsArray => this is ArraySig; - - /// - /// true if it's a - /// - public bool IsSZArray => this is SZArraySig; - - /// - /// true if it's a - /// - public bool IsModifier => this is ModifierSig; - - /// - /// true if it's a - /// - public bool IsRequiredModifier => this is CModReqdSig; - - /// - /// true if it's a - /// - public bool IsOptionalModifier => this is CModOptSig; - - /// - /// true if it's a - /// - public bool IsPinned => this is PinnedSig; - - /// - /// true if it's a - /// - public bool IsValueArray => this is ValueArraySig; - - /// - /// true if it's a - /// - public bool IsModuleSig => this is ModuleSig; - - /// - /// true if this contains a or a - /// . - /// - public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - public override string ToString() => FullName; - } - - public static partial class Extensions { - /// - /// Removes all C optional/required modifiers - /// - /// A instance - /// Input after all modifiers - public static TypeSig RemoveModifiers(this TypeSig a) { - if (a is null) - return null; - while (true) { - var modifier = a as ModifierSig; - if (modifier is null) - return a; - a = a.Next; - } - } - - /// - /// Removes pinned signature - /// - /// The type - /// Input after pinned signature - public static TypeSig RemovePinned(this TypeSig a) { - var pinned = a as PinnedSig; - if (pinned is null) - return a; - return pinned.Next; - } - - /// - /// Removes all modifiers and pinned sig - /// - /// The type - /// Inputer after modifiers and pinned signature - public static TypeSig RemovePinnedAndModifiers(this TypeSig a) { - a = a.RemoveModifiers(); - a = a.RemovePinned(); - a = a.RemoveModifiers(); - return a; - } - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static TypeDefOrRefSig ToTypeDefOrRefSig(this TypeSig type) => type.RemovePinnedAndModifiers() as TypeDefOrRefSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ClassOrValueTypeSig ToClassOrValueTypeSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ClassOrValueTypeSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ValueTypeSig ToValueTypeSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ValueTypeSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ClassSig ToClassSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ClassSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericSig ToGenericSig(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericVar ToGenericVar(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericVar; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericMVar ToGenericMVar(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericMVar; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static GenericInstSig ToGenericInstSig(this TypeSig type) => type.RemovePinnedAndModifiers() as GenericInstSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static PtrSig ToPtrSig(this TypeSig type) => type.RemovePinnedAndModifiers() as PtrSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ByRefSig ToByRefSig(this TypeSig type) => type.RemovePinnedAndModifiers() as ByRefSig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - public static ArraySig ToArraySig(this TypeSig type) => type.RemovePinnedAndModifiers() as ArraySig; - - /// - /// Returns a - /// - /// The type - /// A or null if it's not a - /// - 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) => self?.Next; - - /// - /// Gets the value or false if - /// is null - /// - /// this - /// - public static bool GetIsValueType(this TypeSig self) => self is null ? false : self.IsValueType; - - /// - /// Gets the value or false if - /// is null - /// - /// this - /// - 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 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 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 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 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 . - /// - /// this - /// A or null if none found - public static TypeRef TryGetTypeRef(this TypeSig a) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeRef; - - /// - /// Returns the if it is a . - /// Nothing is resolved. - /// - /// this - /// A or null if none found - 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) => (a.RemovePinnedAndModifiers() as TypeDefOrRefSig)?.TypeSpec; - } - - /// - /// Base class for element types that are last in a type sig, ie., - /// , , , - /// , - /// - public abstract class LeafSig : TypeSig { - /// - public sealed override TypeSig Next => null; - } - - /// - /// Wraps a - /// - public abstract class TypeDefOrRefSig : LeafSig { - readonly ITypeDefOrRef typeDefOrRef; - - /// - /// Gets the the TypeDefOrRef - /// - public ITypeDefOrRef TypeDefOrRef => typeDefOrRef; - - /// - /// Returns true if != null - /// - public bool IsTypeRef => TypeRef is not null; - - /// - /// Returns true if != null - /// - public bool IsTypeDef => TypeDef is not null; - - /// - /// Returns true if != null - /// - public bool IsTypeSpec => TypeSpec is not null; - - /// - /// Gets the or null if it's not a - /// - public TypeRef TypeRef => typeDefOrRef as TypeRef; - - /// - /// Gets the or null if it's not a - /// - public TypeDef TypeDef => typeDefOrRef as TypeDef; - - /// - /// Gets the or null if it's not a - /// - public TypeSpec TypeSpec => typeDefOrRef as TypeSpec; - - /// - /// Constructor - /// - /// A , or - /// a - protected TypeDefOrRefSig(ITypeDefOrRef typeDefOrRef) => this.typeDefOrRef = typeDefOrRef; - } - - /// - /// A core library type - /// - public sealed class CorLibTypeSig : TypeDefOrRefSig { - readonly ElementType elementType; - - /// - /// Gets the element type - /// - public override ElementType ElementType => elementType; - - /// - /// Constructor - /// - /// The type which must be a or a - /// . and null are not allowed. - /// The type's element type - public CorLibTypeSig(ITypeDefOrRef corType, ElementType elementType) - : base(corType) { - if (!(corType is TypeRef) && !(corType is TypeDef)) - throw new ArgumentException("corType must be a TypeDef or a TypeRef. null and TypeSpec are invalid inputs."); - this.elementType = elementType; - } - } - - /// - /// Base class for class/valuetype element types - /// - public abstract class ClassOrValueTypeSig : TypeDefOrRefSig { - /// - /// Constructor - /// - /// A - protected ClassOrValueTypeSig(ITypeDefOrRef typeDefOrRef) - : base(typeDefOrRef) { - } - } - - /// - /// Represents a - /// - public sealed class ValueTypeSig : ClassOrValueTypeSig { - /// - public override ElementType ElementType => ElementType.ValueType; - - /// - /// Constructor - /// - /// A - public ValueTypeSig(ITypeDefOrRef typeDefOrRef) - : base(typeDefOrRef) { - } - } - - /// - /// Represents a - /// - public sealed class ClassSig : ClassOrValueTypeSig { - /// - public override ElementType ElementType => ElementType.Class; - - /// - /// Constructor - /// - /// A - public ClassSig(ITypeDefOrRef typeDefOrRef) - : base(typeDefOrRef) { - } - } - - /// - /// Generic method/type var base class - /// - public abstract class GenericSig : LeafSig { - readonly bool isTypeVar; - readonly uint number; - readonly ITypeOrMethodDef genericParamProvider; - - /// - /// true if it has an owner or - /// - public bool HasOwner => genericParamProvider is not null; - - /// - /// true if it has an owner ( is - /// not null) - /// - public bool HasOwnerType => OwnerType is not null; - - /// - /// true if it has an owner ( is - /// not null) - /// - public bool HasOwnerMethod => OwnerMethod is not null; - - /// - /// Gets the owner type or null if the owner is a or if it - /// has no owner. - /// - 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 => genericParamProvider as MethodDef; - - /// - /// Gets the generic param number - /// - public uint Number => number; - - /// - /// Gets the corresponding or null if none exists. - /// - public GenericParam GenericParam { - get { - var gpp = genericParamProvider; - if (gpp is null) - return null; - 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; - } - return null; - } - } - - /// - /// Constructor - /// - /// true if it's a Var, false if it's a MVar - /// Generic param number - protected GenericSig(bool isTypeVar, uint number) - : this(isTypeVar, number, null) { - } - - /// - /// Constructor - /// - /// true if it's a Var, false if it's a MVar - /// Generic param number - /// Owner method/type or null - protected GenericSig(bool isTypeVar, uint number, ITypeOrMethodDef genericParamProvider) { - this.isTypeVar = isTypeVar; - this.number = number; - this.genericParamProvider = genericParamProvider; - } - - /// - /// Returns true if it's a MVar element type - /// - public bool IsMethodVar => !isTypeVar; - - /// - /// Returns true if it's a Var element type - /// - public bool IsTypeVar => isTypeVar; - } - - /// - /// Represents a - /// - public sealed class GenericVar : GenericSig { - /// - public override ElementType ElementType => ElementType.Var; - - /// - public GenericVar(uint number) - : base(true, number) { - } - - /// - public GenericVar(int number) - : base(true, (uint)number) { - } - - /// - /// Constructor - /// - /// Generic parameter number - /// Owner type or null - public GenericVar(uint number, TypeDef genericParamProvider) - : base(true, number, genericParamProvider) { - } - - /// - /// Constructor - /// - /// Generic parameter number - /// Owner type or null - public GenericVar(int number, TypeDef genericParamProvider) - : base(true, (uint)number, genericParamProvider) { - } - } - - /// - /// Represents a - /// - public sealed class GenericMVar : GenericSig { - /// - public override ElementType ElementType => ElementType.MVar; - - /// - public GenericMVar(uint number) - : base(false, number) { - } - - /// - public GenericMVar(int number) - : base(false, (uint)number) { - } - - /// - /// Constructor - /// - /// Generic parameter number - /// Owner method or null - public GenericMVar(uint number, MethodDef genericParamProvider) - : base(false, number, genericParamProvider) { - } - - /// - /// Constructor - /// - /// Generic parameter number - /// Owner method or null - public GenericMVar(int number, MethodDef genericParamProvider) - : base(false, (uint)number, genericParamProvider) { - } - } - - /// - /// Represents a - /// - public sealed class SentinelSig : LeafSig { - /// - public override ElementType ElementType => ElementType.Sentinel; - } - - /// - /// Represents a - /// - public sealed class FnPtrSig : LeafSig { - readonly CallingConventionSig signature; - - /// - public override ElementType ElementType => ElementType.FnPtr; - - /// - /// Gets the signature - /// - public CallingConventionSig Signature => signature; - - /// - /// Gets the - /// - public MethodSig MethodSig => signature as MethodSig; - - /// - /// Constructor - /// - /// The method signature - public FnPtrSig(CallingConventionSig signature) => this.signature = signature; - } - - /// - /// Represents a - /// - public sealed class GenericInstSig : LeafSig { - ClassOrValueTypeSig genericType; - readonly IList genericArgs; - - /// - public override ElementType ElementType => ElementType.GenericInst; - - /// - /// Gets the generic type - /// - public ClassOrValueTypeSig GenericType { - get => genericType; - set => genericType = value; - } - - /// - /// Gets the generic arguments (it's never null) - /// - public IList GenericArguments => genericArgs; - - /// - /// Default constructor - /// - public GenericInstSig() => genericArgs = new List(); - - /// - /// Constructor - /// - /// The generic type - public GenericInstSig(ClassOrValueTypeSig genericType) { - this.genericType = genericType; - genericArgs = new List(); - } - - /// - /// Constructor - /// - /// The generic type - /// Number of generic arguments - public GenericInstSig(ClassOrValueTypeSig genericType, uint genArgCount) { - this.genericType = genericType; - genericArgs = new List((int)genArgCount); - } - - /// - /// Constructor - /// - /// The generic type - /// Number of generic arguments - public GenericInstSig(ClassOrValueTypeSig genericType, int genArgCount) - : this(genericType, (uint)genArgCount) { - } - - /// - /// Constructor - /// - /// The generic type - /// Generic argument #1 - public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1) { - this.genericType = genericType; - genericArgs = new List { genArg1 }; - } - - /// - /// Constructor - /// - /// The generic type - /// Generic argument #1 - /// Generic argument #2 - public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig genArg2) { - this.genericType = genericType; - genericArgs = new List { genArg1, genArg2 }; - } - - /// - /// Constructor - /// - /// The generic type - /// Generic argument #1 - /// Generic argument #2 - /// Generic argument #3 - public GenericInstSig(ClassOrValueTypeSig genericType, TypeSig genArg1, TypeSig genArg2, TypeSig genArg3) { - this.genericType = genericType; - genericArgs = new List { genArg1, genArg2, genArg3 }; - } - - /// - /// Constructor - /// - /// The generic type - /// Generic arguments - public GenericInstSig(ClassOrValueTypeSig genericType, params TypeSig[] genArgs) { - this.genericType = genericType; - genericArgs = new List(genArgs); - } - - /// - /// Constructor - /// - /// The generic type - /// Generic arguments - public GenericInstSig(ClassOrValueTypeSig genericType, IList genArgs) { - this.genericType = genericType; - genericArgs = new List(genArgs); - } - } - - /// - /// Base class of non-leaf element types - /// - public abstract class NonLeafSig : TypeSig { - readonly TypeSig nextSig; - - /// - public sealed override TypeSig Next => nextSig; - - /// - /// Constructor - /// - /// Next sig - protected NonLeafSig(TypeSig nextSig) => this.nextSig = nextSig; - } - - /// - /// Represents a - /// - public sealed class PtrSig : NonLeafSig { - /// - public override ElementType ElementType => ElementType.Ptr; - - /// - /// Constructor - /// - /// The next element type - public PtrSig(TypeSig nextSig) - : base(nextSig) { - } - } - - /// - /// Represents a - /// - public sealed class ByRefSig : NonLeafSig { - /// - public override ElementType ElementType => ElementType.ByRef; - - /// - /// Constructor - /// - /// The next element type - public ByRefSig(TypeSig nextSig) - : base(nextSig) { - } - } - - /// - /// Array base class - /// - public abstract class ArraySigBase : NonLeafSig { - /// - /// Constructor - /// - /// Array type - protected ArraySigBase(TypeSig arrayType) - : base(arrayType) { - } - - /// - /// true if it's a multi-dimensional array (i.e., ), - /// and false if it's a single-dimensional array (i.e., ) - /// - /// - 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 => ElementType == ElementType.SZArray; - - /// - /// Gets/sets the rank (number of dimensions). This can only be set if - /// is true - /// - public abstract uint Rank { get; set; } - - /// - /// Gets all sizes. If it's a , then it will be an empty temporary - /// list that is re-created every time this method is called. - /// - /// A list of sizes - public abstract IList GetSizes(); - - /// - /// Gets all lower bounds. If it's a , then it will be an empty - /// temporary list that is re-created every time this method is called. - /// - /// A list of lower bounds - public abstract IList GetLowerBounds(); - } - - /// - /// Represents a - /// - /// - public sealed class ArraySig : ArraySigBase { - uint rank; - readonly IList sizes; - readonly IList lowerBounds; - - /// - public override ElementType ElementType => ElementType.Array; - - /// - /// Gets/sets the rank (max value is 0x1FFFFFFF) - /// - public override uint Rank { - get => rank; - set => rank = value; - } - - /// - /// Gets all sizes (max elements is 0x1FFFFFFF) - /// - public IList Sizes => sizes; - - /// - /// Gets all lower bounds (max elements is 0x1FFFFFFF) - /// - public IList LowerBounds => lowerBounds; - - /// - /// Constructor - /// - /// Array type - public ArraySig(TypeSig arrayType) - : base(arrayType) { - sizes = new List(); - lowerBounds = new List(); - } - - /// - /// Constructor - /// - /// Array type - /// Array rank - public ArraySig(TypeSig arrayType, uint rank) - : base(arrayType) { - this.rank = rank; - sizes = new List(); - lowerBounds = new List(); - } - - /// - /// Constructor - /// - /// Array type - /// Array rank - public ArraySig(TypeSig arrayType, int rank) - : this(arrayType, (uint)rank) { - } - - /// - /// Constructor - /// - /// Array type - /// Array rank - /// Sizes list. This instance will be the owner of this list. - /// Lower bounds list. This instance will be the owner of this list. - public ArraySig(TypeSig arrayType, uint rank, IEnumerable sizes, IEnumerable lowerBounds) - : base(arrayType) { - this.rank = rank; - this.sizes = new List(sizes); - this.lowerBounds = new List(lowerBounds); - } - - /// - /// Constructor - /// - /// Array type - /// Array rank - /// Sizes list. This instance will be the owner of this list. - /// Lower bounds list. This instance will be the owner of this list. - public ArraySig(TypeSig arrayType, int rank, IEnumerable sizes, IEnumerable lowerBounds) - : this(arrayType, (uint)rank, sizes, lowerBounds) { - } - - /// - /// Constructor - /// - /// Array type - /// Array rank - /// Sizes list. This instance will be the owner of this list. - /// Lower bounds list. This instance will be the owner of this list. - internal ArraySig(TypeSig arrayType, uint rank, IList sizes, IList lowerBounds) - : base(arrayType) { - this.rank = rank; - this.sizes = sizes; - this.lowerBounds = lowerBounds; - } - - /// - public override IList GetSizes() => sizes; - - /// - public override IList GetLowerBounds() => lowerBounds; - } - - /// - /// Represents a (single dimension, zero lower bound array) - /// - /// - public sealed class SZArraySig : ArraySigBase { - /// - public override ElementType ElementType => ElementType.SZArray; - - /// - public override uint Rank { - get => 1; - set => throw new NotSupportedException(); - } - - /// - /// Constructor - /// - /// The next element type - public SZArraySig(TypeSig nextSig) - : base(nextSig) { - } - - /// - public override IList GetSizes() => Array2.Empty(); - - /// - public override IList GetLowerBounds() => Array2.Empty(); - } - - /// - /// Base class for modifier type sigs - /// - public abstract class ModifierSig : NonLeafSig { - readonly ITypeDefOrRef modifier; - - /// - /// Returns the modifier type - /// - public ITypeDefOrRef Modifier => modifier; - - /// - /// Constructor - /// - /// Modifier type - /// The next element type - protected ModifierSig(ITypeDefOrRef modifier, TypeSig nextSig) - : base(nextSig) => this.modifier = modifier; - } - - /// - /// Represents a - /// - public sealed class CModReqdSig : ModifierSig { - /// - public override ElementType ElementType => ElementType.CModReqd; - - /// - public CModReqdSig(ITypeDefOrRef modifier, TypeSig nextSig) - : base(modifier, nextSig) { - } - } - - /// - /// Represents a - /// - public sealed class CModOptSig : ModifierSig { - /// - public override ElementType ElementType => ElementType.CModOpt; - - /// - public CModOptSig(ITypeDefOrRef modifier, TypeSig nextSig) - : base(modifier, nextSig) { - } - } - - /// - /// Represents a - /// - public sealed class PinnedSig : NonLeafSig { - /// - public override ElementType ElementType => ElementType.Pinned; - - /// - /// Constructor - /// - /// The next element type - public PinnedSig(TypeSig nextSig) - : base(nextSig) { - } - } - - /// - /// Represents a - /// - public sealed class ValueArraySig : NonLeafSig { - uint size; - - /// - public override ElementType ElementType => ElementType.ValueArray; - - /// - /// Gets/sets the size - /// - public uint Size { - get => size; - set => size = value; - } - - /// - /// Constructor - /// - /// The next element type - /// Size of the array - public ValueArraySig(TypeSig nextSig, uint size) - : base(nextSig) => this.size = size; - } - - /// - /// Represents a - /// - public sealed class ModuleSig : NonLeafSig { - uint index; - - /// - public override ElementType ElementType => ElementType.Module; - - /// - /// Gets/sets the index - /// - public uint Index { - get => index; - set => index = value; - } - - /// - /// Constructor - /// - /// Index - /// The next element type - public ModuleSig(uint index, TypeSig nextSig) - : base(nextSig) => this.index = index; - } -} diff --git a/Plugins/dnlib/DotNet/TypeSpec.cs b/Plugins/dnlib/DotNet/TypeSpec.cs deleted file mode 100644 index e7e8206..0000000 --- a/Plugins/dnlib/DotNet/TypeSpec.cs +++ /dev/null @@ -1,339 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.Threading; - -namespace dnlib.DotNet { - /// - /// A high-level representation of a row in the TypeSpec table - /// - public abstract class TypeSpec : ITypeDefOrRef, IHasCustomAttribute, IMemberRefParent, IHasCustomDebugInformation { - /// - /// The row id in its table - /// - protected uint rid; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public MDToken MDToken => new MDToken(Table.TypeSpec, rid); - - /// - public uint Rid { - get => rid; - set => rid = value; - } - - /// - public int TypeDefOrRefTag => 2; - - /// - public int HasCustomAttributeTag => 13; - - /// - public int MemberRefParentTag => 4; - - /// - int IGenericParameterProvider.NumberOfGenericParameters { - get { - var ts = TypeSig; - return ts is null ? 0 : ((IGenericParameterProvider)ts).NumberOfGenericParameters; - } - } - - /// - UTF8String IFullName.Name { - get { - var mr = ScopeType; - return mr is null ? UTF8String.Empty : mr.Name; - } - set { - var mr = ScopeType; - if (mr is not null) - mr.Name = value; - } - } - - /// - ITypeDefOrRef IMemberRef.DeclaringType { - get { - var sig = TypeSig.RemovePinnedAndModifiers(); - - if (sig is GenericInstSig gis) - sig = gis.GenericType; - - 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. - } - - return null; - } - } - - 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 { - get { - var sig = TypeSig; - return sig is not null && sig.IsValueType; - } - } - - /// - public bool IsPrimitive { - get { - var sig = TypeSig; - return sig is not null && sig.IsPrimitive; - } - } - - /// - public string TypeName => FullNameFactory.Name(this, false, null); - - /// - public string ReflectionName => FullNameFactory.Name(this, true, null); - - /// - string IType.Namespace => FullNameFactory.Namespace(this, false, null); - - /// - public string ReflectionNamespace => FullNameFactory.Namespace(this, true, null); - - /// - public string FullName => FullNameFactory.FullName(this, false, null, null); - - /// - public string ReflectionFullName => FullNameFactory.FullName(this, true, null, null); - - /// - public string AssemblyQualifiedName => FullNameFactory.AssemblyQualifiedName(this, null, null); - - /// - public IAssembly DefinitionAssembly => FullNameFactory.DefinitionAssembly(this); - - /// - public IScope Scope => FullNameFactory.Scope(this); - - /// - public ITypeDefOrRef ScopeType => FullNameFactory.ScopeType(this); - - /// - public bool ContainsGenericParameter => TypeHelper.ContainsGenericParameter(this); - - /// - public ModuleDef Module => FullNameFactory.OwnerModule(this); - - /// - /// From column TypeSpec.Signature - /// - public TypeSig TypeSig { - get { - if (!typeSigAndExtraData_isInitialized) - InitializeTypeSigAndExtraData(); - return typeSig; - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - typeSig = value; - if (!typeSigAndExtraData_isInitialized) - GetTypeSigAndExtraData_NoLock(out extraData); - typeSigAndExtraData_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - /// - /// Gets/sets the extra data that was found after the signature - /// - public byte[] ExtraData { - get { - if (!typeSigAndExtraData_isInitialized) - InitializeTypeSigAndExtraData(); - return extraData; - } - set { - if (!typeSigAndExtraData_isInitialized) - InitializeTypeSigAndExtraData(); - extraData = value; - } - } - /// - protected TypeSig typeSig; - /// - protected byte[] extraData; - /// - protected bool typeSigAndExtraData_isInitialized; - - void InitializeTypeSigAndExtraData() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - if (typeSigAndExtraData_isInitialized) - return; - typeSig = GetTypeSigAndExtraData_NoLock(out extraData); - typeSigAndExtraData_isInitialized = true; -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - /// Called to initialize - protected virtual TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { - extraData = null; - return null; - } - - /// - /// 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 => 13; - - /// - public bool HasCustomDebugInfos => CustomDebugInfos.Count > 0; - - /// - /// 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 override string ToString() => FullName; - } - - /// - /// A TypeSpec row created by the user and not present in the original .NET file - /// - public class TypeSpecUser : TypeSpec { - /// - /// Default constructor - /// - public TypeSpecUser() { - } - - /// - /// Constructor - /// - /// A type sig - public TypeSpecUser(TypeSig typeSig) { - this.typeSig = typeSig; - extraData = null; - typeSigAndExtraData_isInitialized = true; - } - } - - /// - /// Created from a row in the TypeSpec table - /// - sealed class TypeSpecMD : TypeSpec, IMDTokenProviderMD, IContainsGenericParameter2 { - /// The module where this instance is located - readonly ModuleDefMD readerModule; - - readonly uint origRid; - readonly GenericParamContext gpContext; - readonly uint signatureOffset; - - /// - public uint OrigRid => origRid; - - /// - protected override TypeSig GetTypeSigAndExtraData_NoLock(out byte[] extraData) { - var sig = readerModule.ReadTypeSignature(signatureOffset, gpContext, out extraData); - if (sig is not null) - sig.Rid = origRid; - return sig; - } - - /// - protected override void InitializeCustomAttributes() { - var list = readerModule.Metadata.GetCustomAttributeRidList(Table.TypeSpec, 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), gpContext, list); - Interlocked.CompareExchange(ref customDebugInfos, list, null); - } - - bool IContainsGenericParameter2.ContainsGenericParameter => ContainsGenericParameter; - - /// - /// Constructor - /// - /// The module which contains this TypeSpec row - /// Row ID - /// Generic parameter context - /// If is null - /// If is invalid - public TypeSpecMD(ModuleDefMD readerModule, uint rid, GenericParamContext gpContext) { -#if DEBUG - if (readerModule is null) - throw new ArgumentNullException("readerModule"); - if (readerModule.TablesStream.TypeSpecTable.IsInvalidRID(rid)) - throw new BadImageFormatException($"TypeSpec rid {rid} does not exist"); -#endif - origRid = rid; - this.rid = rid; - this.readerModule = readerModule; - this.gpContext = gpContext; - bool b = readerModule.TablesStream.TryReadTypeSpecRow(origRid, out var row); - Debug.Assert(b); - signatureOffset = row.Signature; - } - } -} diff --git a/Plugins/dnlib/DotNet/UTF8String.cs b/Plugins/dnlib/DotNet/UTF8String.cs deleted file mode 100644 index 2397ee2..0000000 --- a/Plugins/dnlib/DotNet/UTF8String.cs +++ /dev/null @@ -1,574 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Globalization; -using System.Text; - -namespace dnlib.DotNet { - /// - /// Compares s - /// - public sealed class UTF8StringEqualityComparer : IEqualityComparer { - /// - /// The default instance - /// - public static readonly UTF8StringEqualityComparer Instance = new UTF8StringEqualityComparer(); - - /// - public bool Equals(UTF8String x, UTF8String y) => UTF8String.Equals(x, y); - - /// - public int GetHashCode(UTF8String obj) => UTF8String.GetHashCode(obj); - } - - /// - /// A UTF-8 encoded string where the original data is kept in memory to avoid conversions - /// when the data is not really valid UTF-8 encoded data - /// - /// When comparing strings, a byte compare is performed. The reason is that this - /// is what the CLR does when comparing strings in the #Strings stream. - [DebuggerDisplay("{String}")] - public sealed class UTF8String : IEquatable, IComparable { - /// - /// An empty - /// - public static readonly UTF8String Empty = new UTF8String(string.Empty); - - readonly byte[] data; - string asString; - - /// - /// Gets the value as a UTF8 decoded string. Only use it for display purposes, - /// not for serialization. - /// - public string String { - get { - if (asString is null) - asString = ConvertFromUTF8(data); - return asString; - } - } - - /// - /// Gets the original encoded data. Don't modify this 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 => String.Length; - - /// - /// Gets the length of the raw data. It's the same as 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) => utf8 is null || utf8.data is null; - - /// - /// Checks whether is null or if its data is null or the - /// data is zero length. - /// - /// The instance to check - /// true if null or empty, false otherwise - 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 is null ? null : new UTF8String(s); - - /// - /// Converts it to a - /// - /// The UTF-8 string instace or null - /// A or null if is null - public static string ToSystemString(UTF8String utf8) { - if (utf8 is null || utf8.data is null) - return null; - if (utf8.data.Length == 0) - return string.Empty; - return utf8.String; - } - - /// - /// Converts it to a or an empty string if is null - /// - /// The UTF-8 string instace or null - /// A (never null) - public static string ToSystemStringOrEmpty(UTF8String utf8) => ToSystemString(utf8) ?? string.Empty; - - /// - /// Gets the hash code of a - /// - /// Input - public static int GetHashCode(UTF8String utf8) { - if (IsNullOrEmpty(utf8)) - return 0; - return Utils.GetHashCode(utf8.data); - } - - /// - public int CompareTo(UTF8String other) => CompareTo(this, other); - - /// - /// Compares two instances (case sensitive) - /// - /// 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(a?.data, b?.data); - - /// - /// Compares two instances (case insensitive) - /// - /// Instance #1 or null - /// Instance #2 or null - /// < 0 if a < b, 0 if a == b, > 0 if a > b - public static int CaseInsensitiveCompareTo(UTF8String a, UTF8String b) { - if ((object)a == (object)b) - return 0; - var sa = ToSystemString(a); - var sb = ToSystemString(b); - if ((object)sa == (object)sb) - return 0; - if (sa is null) - return -1; - if (sb is null) - return 1; - return StringComparer.OrdinalIgnoreCase.Compare(sa, sb); - } - - /// - /// Compares two instances (case insensitive) - /// - /// Instance #1 or null - /// Instance #2 or null - /// true if equals, false otherwise - public static bool CaseInsensitiveEquals(UTF8String a, UTF8String b) => CaseInsensitiveCompareTo(a, b) == 0; - - /// Overloaded operator - public static bool operator ==(UTF8String left, UTF8String right) => CompareTo(left, right) == 0; - - /// Overloaded operator - public static bool operator ==(UTF8String left, string right) => ToSystemString(left) == right; - - /// Overloaded operator - public static bool operator ==(string left, UTF8String right) => left == ToSystemString(right); - - /// Overloaded operator - public static bool operator !=(UTF8String left, UTF8String right) => CompareTo(left, right) != 0; - - /// Overloaded operator - public static bool operator !=(UTF8String left, string right) => ToSystemString(left) != right; - - /// Overloaded operator - public static bool operator !=(string left, UTF8String right) => left != ToSystemString(right); - - /// Overloaded operator - public static bool operator >(UTF8String left, UTF8String right) => CompareTo(left, right) > 0; - - /// Overloaded operator - public static bool operator <(UTF8String left, UTF8String right) => CompareTo(left, right) < 0; - - /// Overloaded operator - public static bool operator >=(UTF8String left, UTF8String right) => CompareTo(left, right) >= 0; - - /// Overloaded operator - 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; - - /// - /// Constructor - /// - /// The string - public UTF8String(string s) - : this(s is null ? null : Encoding.UTF8.GetBytes(s)) { - } - - static string ConvertFromUTF8(byte[] data) { - if (data is null) - return null; - try { - return Encoding.UTF8.GetString(data); - } - catch { - } - return null; - } - - /// - /// Compares two instances - /// - /// First - /// Second - /// true if equals, false otherwise - public static bool Equals(UTF8String a, UTF8String b) => CompareTo(a, b) == 0; - - /// - public bool Equals(UTF8String other) => CompareTo(this, other) == 0; - - /// - public override bool Equals(object obj) { - var other = obj as UTF8String; - if (other is null) - return false; - return CompareTo(this, other) == 0; - } - - /// - /// Checks whether exists in this string - /// - /// Value to find - /// true if exists in string or is the - /// empty string, else false - public bool Contains(string value) => String.Contains(value); - - /// - /// Checks whether matches the end of this string - /// - /// Value - /// - public bool EndsWith(string value) => String.EndsWith(value); - - /// - /// Checks whether matches the end of this string - /// - /// Value - /// true to ignore case - /// Culture info - /// - public bool EndsWith(string value, bool ignoreCase, CultureInfo culture) => String.EndsWith(value, ignoreCase, culture); - - /// - /// Checks whether matches the end of this string - /// - /// Value - /// Comparison type - /// - 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) => String.StartsWith(value); - - /// - /// Checks whether matches the beginning of this string - /// - /// Value - /// true to ignore case - /// Culture info - /// - public bool StartsWith(string value, bool ignoreCase, CultureInfo culture) => String.StartsWith(value, ignoreCase, culture); - - /// - /// Checks whether matches the beginning of this string - /// - /// Value - /// Comparison type - /// - 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) => 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) => String.IndexOf(value); - - /// - /// Returns the index of the first character in this string - /// starting from index - /// - /// Character - /// Start index - /// The index of or -1 if not found - public int IndexOf(char value, int startIndex) => String.IndexOf(value, startIndex); - - /// - /// Returns the index of the first character in this string - /// starting from index for max - /// characters. - /// - /// Character - /// 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) => 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) => String.IndexOf(value); - - /// - /// Returns the index of the first sub string in this string - /// starting from index - /// - /// String - /// Start index - /// The index of or -1 if not found - public int IndexOf(string value, int startIndex) => String.IndexOf(value, startIndex); - - /// - /// Returns the index of the first sub string in this string - /// starting from index for max - /// characters. - /// - /// String - /// 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) => String.IndexOf(value, startIndex, count); - - /// - /// Returns the index of the first sub string in this string - /// starting from index for max - /// characters. - /// - /// String - /// Start index - /// 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) => String.IndexOf(value, startIndex, count, comparisonType); - - /// - /// Returns the index of the first sub string in this string - /// starting from index - /// - /// String - /// Start index - /// Comparison type - /// The index of or -1 if not found - 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 - /// - /// String - /// Comparison type - /// The index of or -1 if not found - 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) => String.LastIndexOf(value); - - /// - /// Returns the index of the last character in this string - /// starting from index - /// - /// Character - /// Start index - /// The index of or -1 if not found - public int LastIndexOf(char value, int startIndex) => String.LastIndexOf(value, startIndex); - - /// - /// Returns the index of the last character in this string - /// starting from index for max - /// characters. - /// - /// Character - /// 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) => 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) => String.LastIndexOf(value); - - /// - /// Returns the index of the last sub string in this string - /// starting from index - /// - /// String - /// Start index - /// The index of or -1 if not found - public int LastIndexOf(string value, int startIndex) => String.LastIndexOf(value, startIndex); - - /// - /// Returns the index of the last sub string in this string - /// starting from index for max - /// characters. - /// - /// String - /// 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) => String.LastIndexOf(value, startIndex, count); - - /// - /// Returns the index of the last sub string in this string - /// starting from index for max - /// characters. - /// - /// String - /// Start index - /// 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) => String.LastIndexOf(value, startIndex, count, comparisonType); - - /// - /// Returns the index of the last sub string in this string - /// starting from index - /// - /// String - /// Start index - /// Comparison type - /// The index of or -1 if not found - 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 - /// - /// String - /// Comparison type - /// The index of or -1 if not found - public int LastIndexOf(string value, StringComparison comparisonType) => String.LastIndexOf(value, comparisonType); - - /// - /// Inserts string at a index - /// - /// Start index - /// Value to insert - /// A new instance with the inserted at position - /// - 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) => new UTF8String(String.Remove(startIndex)); - - /// - /// Removes characters starting from position - /// - /// - /// Start index - /// Number of characters to remove - /// A new instance - public UTF8String Remove(int startIndex, int count) => new UTF8String(String.Remove(startIndex, count)); - - /// - /// Replaces all characters with - /// - /// Character to find - /// Character to replace all - /// A new instance - public UTF8String Replace(char oldChar, char newChar) => new UTF8String(String.Replace(oldChar, newChar)); - - /// - /// Replaces all sub strings with - /// - /// Sub string to find - /// Sub string to replace all - /// A new instance - 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) => new UTF8String(String.Substring(startIndex)); - - /// - /// Returns a sub string of this string starting at offset . - /// Length of sub string is . - /// - /// Start index - /// Length of sub string - /// A new instance - 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() => new UTF8String(String.ToLower()); - - /// - /// Returns the lower case version of this string - /// - /// Culture info - /// A new instance - 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() => new UTF8String(String.ToLowerInvariant()); - - /// - /// Returns the upper case version of this string - /// - /// A new instance - 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) => new UTF8String(String.ToUpper(culture)); - - /// - /// Returns the upper case version of this string using the invariant culture - /// - /// A new instance - public UTF8String ToUpperInvariant() => new UTF8String(String.ToUpperInvariant()); - - /// - /// Removes all leading and trailing whitespace characters - /// - /// A new instance - public UTF8String Trim() => new UTF8String(String.Trim()); - - /// - public override int GetHashCode() => UTF8String.GetHashCode(this); - - /// - public override string ToString() => String; - } -} diff --git a/Plugins/dnlib/DotNet/Utils.cs b/Plugins/dnlib/DotNet/Utils.cs deleted file mode 100644 index 90d3797..0000000 --- a/Plugins/dnlib/DotNet/Utils.cs +++ /dev/null @@ -1,293 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Text; - -namespace dnlib.DotNet { - /// - /// Compares byte arrays - /// - sealed class ByteArrayEqualityComparer : IEqualityComparer { - /// - /// Default instance - /// - public static readonly ByteArrayEqualityComparer Instance = new ByteArrayEqualityComparer(); - - /// - public bool Equals(byte[] x, byte[] y) => Utils.Equals(x, y); - - /// - public int GetHashCode(byte[] obj) => Utils.GetHashCode(obj); - } - - static class Utils { - /// - /// Convert a byte[] to a - /// - /// All bytes - /// true if output should be in upper case hex - /// as a hex string - internal static string ToHex(byte[] bytes, bool upper) { - if (bytes is null) - return ""; - var chars = new char[bytes.Length * 2]; - for (int i = 0, j = 0; i < bytes.Length; i++) { - byte b = bytes[i]; - chars[j++] = ToHexChar(b >> 4, upper); - chars[j++] = ToHexChar(b & 0x0F, upper); - } - return new string(chars); - } - - static char ToHexChar(int val, bool upper) { - if (0 <= val && val <= 9) - return (char)(val + (int)'0'); - return (char)(val - 10 + (upper ? (int)'A' : (int)'a')); - } - - /// - /// Converts a hex string to a byte[] - /// - /// A string with an even number of hex characters - /// converted to a byte[] or null - /// if is invalid - internal static byte[] ParseBytes(string hexString) { - try { - if (hexString.Length % 2 != 0) - return null; - var bytes = new byte[hexString.Length / 2]; - for (int i = 0; i < hexString.Length; i += 2) { - int upper = TryParseHexChar(hexString[i]); - int lower = TryParseHexChar(hexString[i + 1]); - if (upper < 0 || lower < 0) - return null; - bytes[i / 2] = (byte)((upper << 4) | lower); - } - return bytes; - } - catch { - return null; - } - } - - /// - /// Converts a character to a hex digit - /// - /// Hex character - /// 0x00-0x0F if successful, -1 if is not - /// a valid hex digit - static int TryParseHexChar(char c) { - if ('0' <= c && c <= '9') - return (ushort)c - (ushort)'0'; - if ('a' <= c && c <= 'f') - return 10 + (ushort)c - (ushort)'a'; - if ('A' <= c && c <= 'F') - return 10 + (ushort)c - (ushort)'A'; - return -1; - } - - /// - /// Compares two byte arrays - /// - /// Byte array #1 - /// Byte array #2 - /// < 0 if a < b, 0 if a == b, > 0 if a > b - internal static int CompareTo(byte[] a, byte[] b) { - if (a == b) - return 0; - if (a is null) - return -1; - if (b is null) - return 1; - int count = Math.Min(a.Length, b.Length); - for (int i = 0; i < count; i++) { - var ai = a[i]; - var bi = b[i]; - if (ai < bi) - return -1; - if (ai > bi) - return 1; - } - return a.Length.CompareTo(b.Length); - } - - /// - /// Checks whether two byte arrays are equal - /// - /// First - /// Second - /// true if same, false otherwise - internal static bool Equals(byte[] a, byte[] b) { - if (a == b) - return true; - if (a is null || b is 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 - /// - /// Byte array - /// The hash code - internal static int GetHashCode(byte[] a) { - if (a is null || a.Length == 0) - return 0; - int count = Math.Min(a.Length / 2, 20); - if (count == 0) - count = 1; - uint hash = 0; - for (int i = 0, j = a.Length - 1; i < count; i++, j--) { - hash ^= a[i] | ((uint)a[j] << 8); - hash = (hash << 13) | (hash >> 19); - } - return (int)hash; - } - - /// - /// Compares two versions - /// - /// This differs from if the build - /// and/or revision numbers haven't been initialized or if one of the args is null. - /// - /// Version #1 or null to be treated as v0.0.0.0 - /// 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 is null) - a = new Version(); - if (b is null) - b = new Version(); - if (a.Major != b.Major) - return a.Major.CompareTo(b.Major); - if (a.Minor != b.Minor) - return a.Minor.CompareTo(b.Minor); - if (GetDefaultVersionValue(a.Build) != GetDefaultVersionValue(b.Build)) - return GetDefaultVersionValue(a.Build).CompareTo(GetDefaultVersionValue(b.Build)); - return GetDefaultVersionValue(a.Revision).CompareTo(GetDefaultVersionValue(b.Revision)); - } - - /// - /// Checks whether two versions are the same - /// - /// This differs from if the build - /// and/or revision numbers haven't been initialized or if one of the args is null. - /// - /// 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) => CompareTo(a, b) == 0; - - /// - /// Creates a new instance with no undefined version values (eg. - /// the build and revision values won't be -1). - /// - /// A instance - /// A new instance - internal static Version CreateVersionWithNoUndefinedValues(Version a) { - if (a is null) - return new Version(0, 0, 0, 0); - return new Version(a.Major, a.Minor, GetDefaultVersionValue(a.Build), GetDefaultVersionValue(a.Revision)); - } - - static int GetDefaultVersionValue(int val) => val == -1 ? 0 : val; - - /// - /// Parses a version string - /// - /// Version string - /// A new or null if - /// is an invalid version - internal static Version ParseVersion(string versionString) { - try { - return Utils.CreateVersionWithNoUndefinedValues(new Version(versionString)); - } - catch { - return null; - } - } - - /// - /// Compares two locales (cultures) - /// - /// First - /// Second - /// < 0 if a < b, 0 if a == b, > 0 if a > b - internal static int LocaleCompareTo(UTF8String a, UTF8String b) => GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); - - /// - /// Compares two locales (cultures) - /// - /// First - /// Second - /// true if same, false otherwise - internal static bool LocaleEquals(UTF8String a, UTF8String b) => LocaleCompareTo(a, b) == 0; - - /// - /// Compares two locales (cultures) - /// - /// First - /// Second - /// < 0 if a < b, 0 if a == b, > 0 if a > b - internal static int LocaleCompareTo(UTF8String a, string b) => GetCanonicalLocale(a).CompareTo(GetCanonicalLocale(b)); - - /// - /// Compares two locales (cultures) - /// - /// First - /// Second - /// true if same, false otherwise - 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) => GetCanonicalLocale(a).GetHashCode(); - - static string GetCanonicalLocale(UTF8String locale) => GetCanonicalLocale(UTF8String.ToSystemStringOrEmpty(locale)); - - static string GetCanonicalLocale(string locale) { - var s = locale.ToUpperInvariant(); - if (s == "NEUTRAL") - s = string.Empty; - return s; - } - - /// - /// Align up - /// - /// Value - /// Alignment - 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) => (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/Plugins/dnlib/DotNet/VTableFixups.cs b/Plugins/dnlib/DotNet/VTableFixups.cs deleted file mode 100644 index 2dfb1c8..0000000 --- a/Plugins/dnlib/DotNet/VTableFixups.cs +++ /dev/null @@ -1,201 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.PE; - -namespace dnlib.DotNet { - /// - /// All native vtables - /// - [DebuggerDisplay("RVA = {RVA}, Count = {VTables.Count}")] - public sealed class VTableFixups : IEnumerable { - RVA rva; - IList vtables; - - /// - /// Gets/sets the RVA of the vtable fixups - /// - public RVA RVA { - get => rva; - set => rva = value; - } - - /// - /// Gets all s - /// - public IList VTables => vtables; - - /// - /// Default constructor - /// - public VTableFixups() => vtables = new List(); - - /// - /// Constructor - /// - /// Module - public VTableFixups(ModuleDefMD module) => Initialize(module); - - void Initialize(ModuleDefMD module) { - var info = module.Metadata.ImageCor20Header.VTableFixups; - if (info.VirtualAddress == 0 || info.Size == 0) { - vtables = new List(); - return; - } - rva = info.VirtualAddress; - vtables = new List((int)info.Size / 8); - - var peImage = module.Metadata.PEImage; - var reader = peImage.CreateReader(); - reader.Position = (uint)peImage.ToFileOffset(info.VirtualAddress); - ulong endPos = (ulong)reader.Position + info.Size; - while ((ulong)reader.Position + 8 <= endPos && reader.CanRead(8U)) { - var tableRva = (RVA)reader.ReadUInt32(); - int numSlots = reader.ReadUInt16(); - var flags = (VTableFlags)reader.ReadUInt16(); - var vtable = new VTable(tableRva, flags, numSlots); - vtables.Add(vtable); - - var pos = reader.Position; - reader.Position = (uint)peImage.ToFileOffset(tableRva); - uint slotSize = vtable.Is64Bit ? 8U : 4; - while (numSlots-- > 0 && reader.CanRead(slotSize)) { - vtable.Methods.Add(module.ResolveToken(reader.ReadUInt32()) as IMethod); - if (slotSize == 8) - reader.ReadUInt32(); - } - reader.Position = pos; - } - } - - /// - public IEnumerator GetEnumerator() => vtables.GetEnumerator(); - - /// - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - } - - /// - /// See COR_VTABLE_XXX in CorHdr.h - /// - [Flags] - public enum VTableFlags : ushort { - /// - /// 32-bit vtable slots - /// - Bit32 = 0x01, - - /// - /// 64-bit vtable slots - /// - Bit64 = 0x02, - - /// - /// Transition from unmanaged code - /// - FromUnmanaged = 0x04, - - /// - /// Also retain app domain - /// - FromUnmanagedRetainAppDomain = 0x08, - - /// - /// Call most derived method - /// - CallMostDerived = 0x10, - } - - /// - /// One VTable accessed by native code - /// - public sealed class VTable : IEnumerable { - RVA rva; - VTableFlags flags; - readonly IList methods; - - /// - /// Gets/sets the of this vtable - /// - public RVA RVA { - get => rva; - set => rva = value; - } - - /// - /// Gets/sets the flags - /// - public VTableFlags Flags { - get => flags; - set => flags = value; - } - - /// - /// true if each vtable slot is 32 bits in size - /// - public bool Is32Bit => (flags & VTableFlags.Bit32) != 0; - - /// - /// true if each vtable slot is 64 bits in size - /// - public bool Is64Bit => (flags & VTableFlags.Bit64) != 0; - - /// - /// Gets the vtable methods - /// - public IList Methods => methods; - - /// - /// Default constructor - /// - public VTable() => methods = new List(); - - /// - /// Constructor - /// - /// Flags - public VTable(VTableFlags flags) { - this.flags = flags; - methods = new List(); - } - - /// - /// Constructor - /// - /// RVA of this vtable - /// Flgas - /// Number of methods in vtable - public VTable(RVA rva, VTableFlags flags, int numSlots) { - this.rva = rva; - this.flags = flags; - methods = new List(numSlots); - } - - /// - /// Constructor - /// - /// RVA of this vtable - /// Flgas - /// Vtable methods - public VTable(RVA rva, VTableFlags flags, IEnumerable methods) { - this.rva = rva; - this.flags = flags; - this.methods = new List(methods); - } - - /// - public IEnumerator GetEnumerator() => methods.GetEnumerator(); - - /// - System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() => GetEnumerator(); - - /// - public override string ToString() { - if (methods.Count == 0) - return $"{methods.Count} {(uint)rva:X8}"; - return $"{methods.Count} {(uint)rva:X8} {methods[0]}"; - } - } -} diff --git a/Plugins/dnlib/DotNet/VariantType.cs b/Plugins/dnlib/DotNet/VariantType.cs deleted file mode 100644 index 5c80ee9..0000000 --- a/Plugins/dnlib/DotNet/VariantType.cs +++ /dev/null @@ -1,117 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// Variant type (VT_XXX in the Windows SDK) - /// - public enum VariantType : uint { - /// - Empty = 0, - /// - None = 0, - /// - Null = 1, - /// - I2 = 2, - /// - I4 = 3, - /// - R4 = 4, - /// - R8 = 5, - /// - CY = 6, - /// - Date = 7, - /// - BStr = 8, - /// - Dispatch = 9, - /// - Error = 10, - /// - Bool = 11, - /// - Variant = 12, - /// - Unknown = 13, - /// - Decimal = 14, - /// - I1 = 16, - /// - UI1 = 17, - /// - UI2 = 18, - /// - UI4 = 19, - /// - I8 = 20, - /// - UI8 = 21, - /// - Int = 22, - /// - UInt = 23, - /// - Void = 24, - /// - HResult = 25, - /// - Ptr = 26, - /// - SafeArray = 27, - /// - CArray = 28, - /// - UserDefined = 29, - /// - LPStr = 30, - /// - LPWStr = 31, - /// - Record = 36, - /// - IntPtr = 37, - /// - UIntPtr = 38, - /// - FileTime = 64, - /// - Blob = 65, - /// - Stream = 66, - /// - Storage = 67, - /// - StreamedObject = 68, - /// - StoredObject = 69, - /// - BlobObject = 70, - /// - CF = 71, - /// - CLSID = 72, - /// - VersionedStream = 73, - /// - BStrBlob = 0x0FFF, - /// - Vector = 0x1000, - /// - Array = 0x2000, - /// - ByRef = 0x4000, - /// - Reserved = 0x8000, - /// - Illegal = 0xFFFF, - /// - IllegalMasked = 0x0FFF, - /// - TypeMask = 0x0FFF, - /// This wasn't present in the blob - NotInitialized = 0xFFFFFFFF, - } -} diff --git a/Plugins/dnlib/DotNet/WinMDHelpers.cs b/Plugins/dnlib/DotNet/WinMDHelpers.cs deleted file mode 100644 index 2211269..0000000 --- a/Plugins/dnlib/DotNet/WinMDHelpers.cs +++ /dev/null @@ -1,446 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet { - enum ClrAssembly { - Mscorlib, - SystemNumericsVectors, - SystemObjectModel, - SystemRuntime, - SystemRuntimeInteropServicesWindowsRuntime, - SystemRuntimeWindowsRuntime, - SystemRuntimeWindowsRuntimeUIXaml, - } - - /// - /// 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; - // Not used when comparing for equality etc - public readonly bool IsValueType; - - public ClassName(UTF8String ns, UTF8String name, bool isValueType = false) { - Namespace = ns; - Name = name; - IsValueType = isValueType; - } - - public ClassName(string ns, string name, bool isValueType = false) { - Namespace = ns; - Name = name; - IsValueType = isValueType; - } - - 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) => - // Don't check IsValueType - UTF8String.Equals(Namespace, other.Namespace) && UTF8String.Equals(Name, other.Name); - - public override bool Equals(object obj) { - if (!(obj is ClassName)) - return false; - return Equals((ClassName)obj); - } - - public override int GetHashCode() => - // Don't use IsValueType - UTF8String.GetHashCode(Namespace) ^ UTF8String.GetHashCode(Name); - - public override string ToString() => $"{Namespace}.{Name}"; - } - - sealed class ProjectedClass { - public readonly ClassName WinMDClass; - public readonly ClassName ClrClass; - public readonly ClrAssembly ClrAssembly; - public readonly ClrAssembly ContractAssembly; - - public ProjectedClass(string mdns, string mdname, string clrns, string clrname, ClrAssembly clrAsm, ClrAssembly contractAsm, bool winMDValueType, bool clrValueType) { - WinMDClass = new ClassName(mdns, mdname, winMDValueType); - ClrClass = new ClassName(clrns, clrname, clrValueType); - ClrAssembly = clrAsm; - ContractAssembly = contractAsm; - } - - public override string ToString() => $"{WinMDClass} <-> {ClrClass}, {CreateAssembly(null, ContractAssembly)}"; - } - - // See https://github.com/dotnet/coreclr/blob/master/src/inc/winrtprojectedtypes.h - // To generate this code replace the contents of src/inc/winrtprojectedtypes.h with: - // DEFINE_PROJECTED_ENUM - // => DEFINE_PROJECTED_STRUCT - // ^DEFINE_PROJECTED\w*_STRUCT\s*\(("[^"]+"),\s*("[^"]+"),\s*("[^"]+"),\s*("[^"]+"),\s*(\w+),\s*(\w+).*$ - // => \t\t\tnew ProjectedClass(\1, \2, \3, \4, ClrAssembly.\5, ClrAssembly.\6, true, true), - // ^DEFINE_PROJECTED\w+\s*\(("[^"]+"),\s*("[^"]+"),\s*("[^"]+"),\s*("[^"]+"),\s*(\w+),\s*(\w+).*$ - // => \t\t\tnew ProjectedClass(\1, \2, \3, \4, ClrAssembly.\5, ClrAssembly.\6, false, false), - // Sometimes the types aren't both structs or both classes. Known cases: - // IReference`1 (class) vs Nullable`1 (struct) - // IKeyValuePair`2 (class) vs KeyValuePair`2 (struct) - // TypeName (struct) vs Type (class) - // HResult (struct) vs Exception (class) - // See md/winmd/adapter.cpp WinMDAdapter::RewriteTypeInSignature() or check the types - // in a decompiler. - static readonly ProjectedClass[] ProjectedClasses = new ProjectedClass[] { - new ProjectedClass("Windows.Foundation.Metadata", "AttributeUsageAttribute", "System", "AttributeUsageAttribute", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Metadata", "AttributeTargets", "System", "AttributeTargets", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, true, true), - - new ProjectedClass("Windows.UI", "Color", "Windows.UI", "Color", ClrAssembly.SystemRuntimeWindowsRuntime, ClrAssembly.SystemRuntimeWindowsRuntime, true, true), - - new ProjectedClass("Windows.Foundation", "DateTime", "System", "DateTimeOffset", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, true, true), - new ProjectedClass("Windows.Foundation", "EventHandler`1", "System", "EventHandler`1", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation", "EventRegistrationToken", "System.Runtime.InteropServices.WindowsRuntime", "EventRegistrationToken", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntimeInteropServicesWindowsRuntime, true, true), - new ProjectedClass("Windows.Foundation", "HResult", "System", "Exception", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, true, false), - new ProjectedClass("Windows.Foundation", "IReference`1", "System", "Nullable`1", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, true), - new ProjectedClass("Windows.Foundation", "Point", "Windows.Foundation", "Point", ClrAssembly.SystemRuntimeWindowsRuntime, ClrAssembly.SystemRuntimeWindowsRuntime, true, true), - new ProjectedClass("Windows.Foundation", "Rect", "Windows.Foundation", "Rect", ClrAssembly.SystemRuntimeWindowsRuntime, ClrAssembly.SystemRuntimeWindowsRuntime, true, true), - new ProjectedClass("Windows.Foundation", "Size", "Windows.Foundation", "Size", ClrAssembly.SystemRuntimeWindowsRuntime, ClrAssembly.SystemRuntimeWindowsRuntime, true, true), - new ProjectedClass("Windows.Foundation", "TimeSpan", "System", "TimeSpan", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, true, true), - new ProjectedClass("Windows.Foundation", "Uri", "System", "Uri", ClrAssembly.SystemRuntime, ClrAssembly.SystemRuntime, false, false), - - new ProjectedClass("Windows.Foundation", "IClosable", "System", "IDisposable", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - - new ProjectedClass("Windows.Foundation.Collections", "IIterable`1", "System.Collections.Generic", "IEnumerable`1", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Collections", "IVector`1", "System.Collections.Generic", "IList`1", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Collections", "IVectorView`1", "System.Collections.Generic", "IReadOnlyList`1", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Collections", "IMap`2", "System.Collections.Generic", "IDictionary`2", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Collections", "IMapView`2", "System.Collections.Generic", "IReadOnlyDictionary`2", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.Foundation.Collections", "IKeyValuePair`2", "System.Collections.Generic", "KeyValuePair`2", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, true), - - new ProjectedClass("Windows.UI.Xaml.Input", "ICommand", "System.Windows.Input", "ICommand", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - - new ProjectedClass("Windows.UI.Xaml.Interop", "IBindableIterable", "System.Collections", "IEnumerable", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - new ProjectedClass("Windows.UI.Xaml.Interop", "IBindableVector", "System.Collections", "IList", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, false, false), - - new ProjectedClass("Windows.UI.Xaml.Interop", "INotifyCollectionChanged", "System.Collections.Specialized", "INotifyCollectionChanged", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - new ProjectedClass("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventHandler", "System.Collections.Specialized", "NotifyCollectionChangedEventHandler", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - new ProjectedClass("Windows.UI.Xaml.Interop", "NotifyCollectionChangedEventArgs", "System.Collections.Specialized", "NotifyCollectionChangedEventArgs", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - new ProjectedClass("Windows.UI.Xaml.Interop", "NotifyCollectionChangedAction", "System.Collections.Specialized", "NotifyCollectionChangedAction", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, true, true), - - new ProjectedClass("Windows.UI.Xaml.Data", "INotifyPropertyChanged", "System.ComponentModel", "INotifyPropertyChanged", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - new ProjectedClass("Windows.UI.Xaml.Data", "PropertyChangedEventHandler", "System.ComponentModel", "PropertyChangedEventHandler", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - new ProjectedClass("Windows.UI.Xaml.Data", "PropertyChangedEventArgs", "System.ComponentModel", "PropertyChangedEventArgs", ClrAssembly.SystemObjectModel, ClrAssembly.SystemObjectModel, false, false), - - new ProjectedClass("Windows.UI.Xaml", "CornerRadius", "Windows.UI.Xaml", "CornerRadius", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml", "Duration", "Windows.UI.Xaml", "Duration", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml", "DurationType", "Windows.UI.Xaml", "DurationType", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml", "GridLength", "Windows.UI.Xaml", "GridLength", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml", "GridUnitType", "Windows.UI.Xaml", "GridUnitType", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml", "Thickness", "Windows.UI.Xaml", "Thickness", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - - new ProjectedClass("Windows.UI.Xaml.Interop", "TypeName", "System", "Type", ClrAssembly.Mscorlib, ClrAssembly.SystemRuntime, true, false), - - new ProjectedClass("Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", "Windows.UI.Xaml.Controls.Primitives", "GeneratorPosition", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - - new ProjectedClass("Windows.UI.Xaml.Media", "Matrix", "Windows.UI.Xaml.Media", "Matrix", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - - new ProjectedClass("Windows.UI.Xaml.Media.Animation", "KeyTime", "Windows.UI.Xaml.Media.Animation", "KeyTime", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml.Media.Animation", "RepeatBehavior", "Windows.UI.Xaml.Media.Animation", "RepeatBehavior", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - new ProjectedClass("Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", "Windows.UI.Xaml.Media.Animation", "RepeatBehaviorType", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - - new ProjectedClass("Windows.UI.Xaml.Media.Media3D", "Matrix3D", "Windows.UI.Xaml.Media.Media3D", "Matrix3D", ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, ClrAssembly.SystemRuntimeWindowsRuntimeUIXaml, true, true), - - new ProjectedClass("Windows.Foundation.Numerics", "Vector2", "System.Numerics", "Vector2", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Vector3", "System.Numerics", "Vector3", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Vector4", "System.Numerics", "Vector4", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Matrix3x2", "System.Numerics", "Matrix3x2", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Matrix4x4", "System.Numerics", "Matrix4x4", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Plane", "System.Numerics", "Plane", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - new ProjectedClass("Windows.Foundation.Numerics", "Quaternion", "System.Numerics", "Quaternion", ClrAssembly.SystemNumericsVectors, ClrAssembly.SystemNumericsVectors, true, true), - }; - - static readonly Dictionary winMDToCLR = new Dictionary(); - - static WinMDHelpers() { - foreach (var projClass in ProjectedClasses) - winMDToCLR.Add(projClass.WinMDClass, projClass); - } - - static AssemblyRef ToCLR(ModuleDef module, ref UTF8String ns, ref UTF8String name) { - if (!winMDToCLR.TryGetValue(new ClassName(ns, name), out var pc)) - return null; - - ns = pc.ClrClass.Namespace; - name = pc.ClrClass.Name; - return CreateAssembly(module, pc.ContractAssembly); - } - - 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 not null && mscorlib.Name == mscorlibName && IsValidMscorlibVersion(mscorlib.Version)) - asm.Version = mscorlib.Version; - if (module is ModuleDefMD mod) { - Version ver = null; - foreach (var asmRef in mod.GetAssemblyRefs()) { - if (asmRef.IsContentTypeWindowsRuntime) - continue; - if (asmRef.Name != asm.Name) - continue; - if (asmRef.Culture != asm.Culture) - continue; - if (!PublicKeyBase.TokenEquals(asmRef.PublicKeyOrToken, asm.PublicKeyOrToken)) - continue; - if (!IsValidMscorlibVersion(asmRef.Version)) - continue; - - if (ver is null || asmRef.Version > ver) - ver = asmRef.Version; - } - if (ver is not null) - asm.Version = ver; - } - - return asm; - } - static readonly Version contractAsmVersion = new Version(4, 0, 0, 0); - static readonly UTF8String mscorlibName = new UTF8String("mscorlib"); - - // Silverlight uses 5.0.5.0 - static bool IsValidMscorlibVersion(Version version) => version is not null && (uint)version.Major <= 5; - - 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"); - static readonly UTF8String clrAsmName_SystemRuntime = new UTF8String("System.Runtime"); - static readonly UTF8String clrAsmName_SystemRuntimeInteropServicesWindowsRuntime = new UTF8String("System.Runtime.InteropServices.WindowsRuntime"); - 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) => - 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 }; - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// - public static TypeRef ToCLR(ModuleDef module, TypeDef td) => ToCLR(module, td, out bool isClrValueType); - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// true if the returned type is a value type - /// - public static TypeRef ToCLR(ModuleDef module, TypeDef td, out bool isClrValueType) { - isClrValueType = false; - if (td is null || !td.IsWindowsRuntime) - return null; - var asm = td.DefinitionAssembly; - if (asm is null || !asm.IsContentTypeWindowsRuntime) - return null; - - if (!winMDToCLR.TryGetValue(new ClassName(td.Namespace, td.Name), out var pc)) - return null; - - isClrValueType = pc.ClrClass.IsValueType; - return new TypeRefUser(module, pc.ClrClass.Namespace, pc.ClrClass.Name, CreateAssembly(module, pc.ContractAssembly)); - } - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// - public static TypeRef ToCLR(ModuleDef module, TypeRef tr) => ToCLR(module, tr, out bool isClrValueType); - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// true if the returned type is a value type - /// - public static TypeRef ToCLR(ModuleDef module, TypeRef tr, out bool isClrValueType) { - isClrValueType = false; - if (tr is null) - return null; - var defAsm = tr.DefinitionAssembly; - if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) - return null; - if (tr.DeclaringType is not null) - return null; - - if (!winMDToCLR.TryGetValue(new ClassName(tr.Namespace, tr.Name), out var pc)) - return null; - - isClrValueType = pc.ClrClass.IsValueType; - return new TypeRefUser(module, pc.ClrClass.Namespace, pc.ClrClass.Name, CreateAssembly(module, pc.ContractAssembly)); - } - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// - public static ExportedType ToCLR(ModuleDef module, ExportedType et) { - if (et is null) - return null; - var defAsm = et.DefinitionAssembly; - if (defAsm is null || !defAsm.IsContentTypeWindowsRuntime) - return null; - if (et.DeclaringType is not null) - return null; - - 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)); - } - - /// - /// Converts WinMD type to a CLR type. Returns null - /// if it's not a CLR compatible WinMD type. - /// - /// Owner module or null - /// Type - /// - public static TypeSig ToCLR(ModuleDef module, TypeSig ts) { - if (ts is null) - return null; - var et = ts.ElementType; - if (et != ElementType.Class && et != ElementType.ValueType) - return null; - - var tdr = ((ClassOrValueTypeSig)ts).TypeDefOrRef; - - TypeRef tr, newTr; - bool isClrValueType; - if (tdr is TypeDef td) { - newTr = ToCLR(module, td, out isClrValueType); - if (newTr is null) - return null; - } - else if ((tr = tdr as TypeRef) is not null) { - newTr = ToCLR(module, tr, out isClrValueType); - if (newTr is null) - return null; - } - else - return null; - - return isClrValueType ? - (TypeSig)new ValueTypeSig(newTr) : - new ClassSig(newTr); - } - - /// - /// Converts WinMD member reference to a CLR member reference. Returns - /// null if it's not a CLR compatible WinMD member reference. - /// - /// Owner module or null - /// Member reference - /// - public static MemberRef ToCLR(ModuleDef module, MemberRef mr) { - // See WinMDAdapter::CheckIfMethodImplImplementsARedirectedInterface - // in coreclr: md/winmd/adapter.cpp - if (mr is null) - return null; - if (mr.Name != CloseName) - return null; - - var msig = mr.MethodSig; - if (msig is null) - return null; - - var cl = mr.Class; - IMemberRefParent newCl; - TypeSpec ts; - if (cl is TypeRef tr) { - var newTr = ToCLR(module, tr); - if (newTr is null || !IsIDisposable(newTr)) - return null; - - newCl = newTr; - } - 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; - tr = gis.GenericType.TypeRef; - if (tr is null) - return null; - - var newTr = ToCLR(module, tr, out bool isClrValueType); - if (newTr is null || !IsIDisposable(newTr)) - return null; - - newCl = new TypeSpecUser(new GenericInstSig(isClrValueType ? - (ClassOrValueTypeSig)new ValueTypeSig(newTr) : - new ClassSig(newTr), gis.GenericArguments)); - } - else - return null; - - return new MemberRefUser(mr.Module, DisposeName, msig, newCl); - } - static readonly UTF8String CloseName = new UTF8String("Close"); - static readonly UTF8String DisposeName = new UTF8String("Dispose"); - - 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"); - - /// - /// Converts WinMD method to a CLR member reference. Returns - /// null if it's not a CLR compatible WinMD method - /// - /// Owner module or null - /// Method - /// - public static MemberRef ToCLR(ModuleDef module, MethodDef md) { - if (md is null) - return null; - if (md.Name != CloseName) - return null; - var declType = md.DeclaringType; - if (declType is null) - return null; - - var tr = ToCLR(module, declType); - if (tr is null || !IsIDisposable(tr)) - return null; - - return new MemberRefUser(md.Module, DisposeName, md.MethodSig, tr); - } - } -} diff --git a/Plugins/dnlib/DotNet/WinMDStatus.cs b/Plugins/dnlib/DotNet/WinMDStatus.cs deleted file mode 100644 index d60cb7e..0000000 --- a/Plugins/dnlib/DotNet/WinMDStatus.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet { - /// - /// WinMD status - /// - public enum WinMDStatus { - /// - /// This is not a WinMD file - /// - None, - - /// - /// This is a pure WinMD file (not managed) - /// - Pure, - - /// - /// This is a managed WinMD file (created by eg. winmdexp.exe) - /// - Managed, - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ArrayWriter.cs b/Plugins/dnlib/DotNet/Writer/ArrayWriter.cs deleted file mode 100644 index d3e7f16..0000000 --- a/Plugins/dnlib/DotNet/Writer/ArrayWriter.cs +++ /dev/null @@ -1,152 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; - -namespace dnlib.DotNet.Writer { - /// - /// Writes data - /// - public unsafe struct ArrayWriter { - /// - /// Gets the current position - /// - public int Position { - get => position; - set => position = value; - } - - readonly byte[] data; - int position; - - /// - /// Constructor - /// - /// Destination array - public ArrayWriter(byte[] data) { - this.data = data; - position = 0; - } - - internal byte[] DataUnsafe => data; - - /// - /// 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; - fixed (byte* p = data) - *(int*)(p + position) = value; - this.position = position + 4; - } - - /// - /// Writes a - /// - /// Value - public void WriteUInt32(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; - } - - /// - /// Writes a - /// - /// Value - public void WriteInt64(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; - } - - /// - /// Writes a - /// - /// Value - public void WriteUInt64(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; - } - - /// - /// Writes a - /// - /// Value - public void WriteSingle(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; - } - - /// - /// Writes a - /// - /// Value - public void WriteDouble(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; - } - - /// - /// 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/Plugins/dnlib/DotNet/Writer/BlobHeap.cs b/Plugins/dnlib/DotNet/Writer/BlobHeap.cs deleted file mode 100644 index 80fcff0..0000000 --- a/Plugins/dnlib/DotNet/Writer/BlobHeap.cs +++ /dev/null @@ -1,151 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using dnlib.IO; -using dnlib.DotNet.MD; -using dnlib.Protection; - -namespace dnlib.DotNet.Writer { - /// - /// #Blob heap - /// - public sealed class BlobHeap : HeapBase, IOffsetHeap { - readonly Dictionary cachedDict = new Dictionary(ByteArrayEqualityComparer.Instance); - readonly List cached = new List(); - uint nextOffset = 1; - byte[] originalData; - Dictionary userRawData; - - /// - public override string Name => "#Blob"; - - /// - /// Populates blobs from an existing (eg. to preserve - /// blob offsets) - /// - /// The #Blob stream with the original content - public void Populate(BlobStream blobStream) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - if (originalData is not null) - throw new InvalidOperationException("Can't call method twice"); - if (nextOffset != 1) - throw new InvalidOperationException("Add() has already been called"); - if (blobStream is null || blobStream.StreamLength == 0) - return; - - var reader = blobStream.CreateReader(); - originalData = reader.ToArray(); - nextOffset = (uint)originalData.Length; - Populate(ref reader); - } - - void Populate(ref DataReader reader) { - reader.Position = 1; - while (reader.Position < reader.Length) { - uint offset = reader.Position; - if (!reader.TryReadCompressedUInt32(out uint len)) { - if (offset == reader.Position) - reader.Position++; - continue; - } - if (len == 0 || (ulong)reader.Position + len > reader.Length) - continue; - - var data = reader.ReadBytes((int)len); - if (!cachedDict.ContainsKey(data)) - cachedDict[data] = offset; - } - } - - /// - /// Adds data to the #Blob heap - /// - /// The data - /// The offset of the data in the #Blob heap - public uint Add(byte[] data) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - if (data is null || data.Length == 0) - return 0; - - if (cachedDict.TryGetValue(data, out uint offset)) - return offset; - return AddToCache(data); - } - - /// - /// Adds data to the #Blob heap, but does not re-use an existing position - /// - /// The data - /// The offset of the data in the #Blob heap - public uint Create(byte[] data) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #Blob when it's read-only"); - return AddToCache(data ?? Array2.Empty()); - } - - uint AddToCache(byte[] data) { - uint offset; - cached.Add(data); - cachedDict[data] = offset = nextOffset; - nextOffset += (uint)GetRawDataSize(data); - return offset; - } - - /// - public override uint GetRawLength() => nextOffset; - - protected override EncryptionMethod GetEncryptionMethod(IEncryption e) => e.BlobEnc; - - /// - protected override void WriteToImpl(DataWriter writer) { - if (originalData is not null) - writer.WriteBytes(originalData); - else - writer.WriteByte(0); - - uint offset = originalData is not null ? (uint)originalData.Length : 1; - foreach (var data in cached) { - int rawLen = GetRawDataSize(data); - 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); - } - else { - writer.WriteCompressedUInt32((uint)data.Length); - writer.WriteBytes(data); - } - offset += (uint)rawLen; - } - } - - /// - public int GetRawDataSize(byte[] data) => DataWriter.GetCompressedUInt32Length((uint)data.Length) + data.Length; - - /// - public void SetRawData(uint offset, byte[] rawData) { - if (userRawData is null) - userRawData = new Dictionary(); - userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); - } - - /// - public IEnumerable> GetAllRawData() { - var memStream = new MemoryStream(); - var writer = new DataWriter(memStream); - uint offset = originalData is not null ? (uint)originalData.Length : 1; - foreach (var data in cached) { - memStream.Position = 0; - memStream.SetLength(0); - writer.WriteCompressedUInt32((uint)data.Length); - writer.WriteBytes(data); - yield return new KeyValuePair(offset, memStream.ToArray()); - offset += (uint)memStream.Length; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ByteArrayChunk.cs b/Plugins/dnlib/DotNet/Writer/ByteArrayChunk.cs deleted file mode 100644 index 4a6b4c3..0000000 --- a/Plugins/dnlib/DotNet/Writer/ByteArrayChunk.cs +++ /dev/null @@ -1,71 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Stores a byte array - /// - public sealed class ByteArrayChunk : IReuseChunk { - readonly byte[] array; - readonly uint alignment; - FileOffset offset; - RVA rva; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets the data - /// - public byte[] Data => array; - - /// - /// Constructor - /// - /// The data. It will be owned by this instance and can't be modified by - /// other code if this instance is inserted as a key in a dictionary (because - /// 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. - /// 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; - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - } - - /// - public uint GetFileLength() => (uint)array.Length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => alignment; - - /// - public void WriteTo(DataWriter writer) => writer.WriteBytes(array); - - /// - public override int GetHashCode() => Utils.GetHashCode(array); - - /// - public override bool Equals(object obj) { - var other = obj as ByteArrayChunk; - return other is not null && Utils.Equals(array, other.array); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ChecksumAlgorithm.cs b/Plugins/dnlib/DotNet/Writer/ChecksumAlgorithm.cs deleted file mode 100644 index c009418..0000000 --- a/Plugins/dnlib/DotNet/Writer/ChecksumAlgorithm.cs +++ /dev/null @@ -1,28 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Writer/ChunkList.cs b/Plugins/dnlib/DotNet/Writer/ChunkList.cs deleted file mode 100644 index 2f2fd08..0000000 --- a/Plugins/dnlib/DotNet/Writer/ChunkList.cs +++ /dev/null @@ -1,49 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet.Writer { - /// - /// Contains a list of s - /// - public class ChunkList : ChunkListBase where T : class, IChunk { - /// - /// Default constructor - /// - public ChunkList() => chunks = new List(); - - /// - /// Add a - /// - /// The chunk to add or null if none - /// Chunk alignment - public void Add(T chunk, uint alignment) { - if (setOffsetCalled) - throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk is not null) - chunks.Add(new Elem(chunk, alignment)); - } - - /// - /// Remove a - /// - /// The chunk to remove or null if none - /// Alignment of the chunk, or null if the chunk cannot be removed. - public uint? Remove(T chunk) { - if (setOffsetCalled) - throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk is not null) { - var chunks = this.chunks; - for (int i = 0; i < chunks.Count; i++) { - if (chunks[i].chunk == chunk) { - uint alignment = chunks[i].alignment; - chunks.RemoveAt(i); - return alignment; - } - } - } - return null; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ChunkListBase.cs b/Plugins/dnlib/DotNet/Writer/ChunkListBase.cs deleted file mode 100644 index b7bd2b4..0000000 --- a/Plugins/dnlib/DotNet/Writer/ChunkListBase.cs +++ /dev/null @@ -1,133 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Base class of chunk list types - /// - /// Chunk type - public abstract class ChunkListBase : IChunk where T : IChunk { - /// All chunks - protected List chunks; - uint length; - uint virtualSize; - /// true if has been called - protected bool setOffsetCalled; - FileOffset offset; - RVA rva; - - internal bool IsEmpty => chunks.Count == 0; - - /// - /// Helper struct - /// - protected readonly struct Elem { - /// Data - public readonly T chunk; - /// Alignment - public readonly uint alignment; - - /// - /// Constructor - /// - /// Chunk - /// Alignment - public Elem(T chunk, uint alignment) { - this.chunk = chunk; - this.alignment = alignment; - } - } - - /// - /// Equality comparer for - /// - protected sealed class ElemEqualityComparer : IEqualityComparer { - IEqualityComparer chunkComparer; - - /// - /// Constructor - /// - /// Compares the chunk type - public ElemEqualityComparer(IEqualityComparer chunkComparer) => this.chunkComparer = chunkComparer; - - /// - public bool Equals(Elem x, Elem y) => - x.alignment == y.alignment && - chunkComparer.Equals(x.chunk, y.chunk); - - /// - public int GetHashCode(Elem obj) => (int)obj.alignment + chunkComparer.GetHashCode(obj.chunk); - } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - public virtual void SetOffset(FileOffset offset, RVA rva) { - setOffsetCalled = true; - this.offset = offset; - this.rva = rva; - length = 0; - virtualSize = 0; - foreach (var elem in chunks) { - uint paddingF = (uint)offset.AlignUp(elem.alignment) - (uint)offset; - uint paddingV = (uint)rva.AlignUp(elem.alignment) - (uint)rva; - offset += paddingF; - rva += paddingV; - elem.chunk.SetOffset(offset, rva); - 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; - } - } - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => virtualSize; - - /// - public void WriteTo(DataWriter writer) { - var offset2 = offset; - foreach (var elem in chunks) { - if (elem.chunk.GetVirtualSize() == 0) - continue; - int paddingF = (int)offset2.AlignUp(elem.alignment) - (int)offset2; - writer.WriteZeroes(paddingF); - elem.chunk.VerifyWriteTo(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/Plugins/dnlib/DotNet/Writer/CustomAttributeWriter.cs b/Plugins/dnlib/DotNet/Writer/CustomAttributeWriter.cs deleted file mode 100644 index 2aed607..0000000 --- a/Plugins/dnlib/DotNet/Writer/CustomAttributeWriter.cs +++ /dev/null @@ -1,764 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace dnlib.DotNet.Writer { - /// - /// Helps write custom attributes - /// - public interface ICustomAttributeWriterHelper : IWriterError, IFullNameFactoryHelper { - } - - /// - /// Writes s - /// - public struct CustomAttributeWriter : IDisposable { - readonly ICustomAttributeWriterHelper helper; - RecursionCounter recursionCounter; - readonly StringBuilder sb; - readonly MemoryStream outStream; - readonly DataWriter writer; - readonly bool disposeStream; - GenericArguments genericArguments; - - /// - /// Writes a custom attribute - /// - /// Helper class - /// The custom attribute - /// Custom attribute blob - public static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca) { - using (var writer = new CustomAttributeWriter(helper)) { - writer.Write(ca); - return writer.GetResult(); - } - } - - internal static byte[] Write(ICustomAttributeWriterHelper helper, CustomAttribute ca, DataWriterContext context) { - using (var writer = new CustomAttributeWriter(helper, context)) { - writer.Write(ca); - return writer.GetResult(); - } - } - - /// - /// Writes custom attribute named arguments - /// - /// Helper class - /// Named arguments - /// The named args blob - internal static byte[] Write(ICustomAttributeWriterHelper helper, IList namedArgs) { - using (var writer = new CustomAttributeWriter(helper)) { - writer.Write(namedArgs); - return writer.GetResult(); - } - } - - internal static byte[] Write(ICustomAttributeWriterHelper helper, IList namedArgs, DataWriterContext context) { - using (var writer = new CustomAttributeWriter(helper, context)) { - writer.Write(namedArgs); - return writer.GetResult(); - } - } - - CustomAttributeWriter(ICustomAttributeWriterHelper helper) { - this.helper = helper; - recursionCounter = new RecursionCounter(); - sb = new StringBuilder(); - outStream = new MemoryStream(); - writer = new DataWriter(outStream); - genericArguments = null; - disposeStream = true; - } - - CustomAttributeWriter(ICustomAttributeWriterHelper helper, DataWriterContext context) { - this.helper = helper; - recursionCounter = new RecursionCounter(); - sb = new StringBuilder(); - outStream = context.OutStream; - writer = context.Writer; - genericArguments = null; - disposeStream = false; - outStream.SetLength(0); - outStream.Position = 0; - } - - byte[] GetResult() => outStream.ToArray(); - - void Write(CustomAttribute ca) { - if (ca is null) { - helper.Error("The custom attribute is null"); - return; - } - - // 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 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; - } - - if (ca.Constructor is null) { - helper.Error("Custom attribute ctor is null"); - return; - } - - var methodSig = GetMethodSig(ca.Constructor); - 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 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"); - - if (ca.Constructor is MemberRef mrCtor && mrCtor.Class is TypeSpec owner && owner.TypeSig is GenericInstSig gis) { - genericArguments = new GenericArguments(); - genericArguments.PushTypeArgs(gis.GenericArguments); - } - - 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.WriteUInt16((ushort)numNamedArgs); - for (int i = 0; i < numNamedArgs; i++) - Write(ca.NamedArguments[i]); - } - - void Write(IList namedArgs) { - if (namedArgs is null || namedArgs.Count > 0x1FFFFFFF) { - helper.Error("Too many custom attribute named arguments"); - namedArgs = Array2.Empty(); - } - writer.WriteCompressedUInt32((uint)namedArgs.Count); - for (int i = 0; i < namedArgs.Count; i++) - Write(namedArgs[i]); - } - - TypeSig FixTypeSig(TypeSig type) => SubstituteGenericParameter(type.RemoveModifiers()).RemoveModifiers(); - - TypeSig SubstituteGenericParameter(TypeSig type) { - if (genericArguments is null) - return type; - return genericArguments.Resolve(type); - } - - void WriteValue(TypeSig argType, CAArgument value) { - if (argType is null || value.Type is null) { - helper.Error("Custom attribute argument type is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - if (argType is SZArraySig arrayType) { - var argsArray = value.Value as IList; - if (argsArray is null && value.Value is not null) - helper.Error("CAArgument.Value is not null or an array"); - WriteArrayValue(arrayType, argsArray); - } - else - WriteElem(argType, value); - - recursionCounter.Decrement(); - } - - void WriteArrayValue(SZArraySig arrayType, IList args) { - if (arrayType is null) { - helper.Error("Custom attribute: Array type is null"); - return; - } - - if (args is null) - writer.WriteUInt32(uint.MaxValue); - else { - writer.WriteUInt32((uint)args.Count); - var arrayElementType = FixTypeSig(arrayType.Next); - for (int i = 0; i < args.Count; i++) - WriteValue(arrayElementType, args[i]); - } - } - - bool VerifyTypeAndValue(CAArgument value, ElementType etype) { - if (!VerifyType(value.Type, etype)) { - helper.Error("Custom attribute arg type != value.Type"); - return false; - } - if (!VerifyValue(value.Value, etype)) { - helper.Error("Custom attribute value.Value's type != value.Type"); - return false; - } - return true; - } - - bool VerifyTypeAndValue(CAArgument value, ElementType etype, Type valueType) { - if (!VerifyType(value.Type, etype)) { - helper.Error("Custom attribute arg type != value.Type"); - return false; - } - 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 is not null && (etype == type.ElementType || type.ElementType == ElementType.ValueType); - } - - static bool VerifyValue(object o, ElementType etype) { - if (o is null) - 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) { - ToUInt64(o, out ulong result); - return result; - } - - static bool ToUInt64(object o, out ulong result) { - if (o is null) { - result = 0; - return false; - } - - switch (Type.GetTypeCode(o.GetType())) { - case TypeCode.Boolean: - result = (bool)o ? 1UL : 0UL; - return true; - - case TypeCode.Char: - result = (ushort)(char)o; - return true; - - case TypeCode.SByte: - result = (ulong)(sbyte)o; - return true; - - case TypeCode.Byte: - result = (byte)o; - return true; - - case TypeCode.Int16: - result = (ulong)(short)o; - return true; - - case TypeCode.UInt16: - result = (ushort)o; - return true; - - case TypeCode.Int32: - result = (ulong)(int)o; - return true; - - case TypeCode.UInt32: - result = (uint)o; - return true; - - case TypeCode.Int64: - result = (ulong)(long)o; - return true; - - case TypeCode.UInt64: - result = (ulong)o; - return true; - - case TypeCode.Single: - result = (ulong)(float)o; - return true; - - case TypeCode.Double: - result = (ulong)(double)o; - return true; - } - - result = 0; - return false; - } - - static double ToDouble(object o) { - ToDouble(o, out double result); - return result; - } - - static bool ToDouble(object o, out double result) { - if (o is null) { - result = double.NaN; - return false; - } - - switch (Type.GetTypeCode(o.GetType())) { - case TypeCode.Boolean: - result = (bool)o ? 1 : 0; - return true; - - case TypeCode.Char: - result = (ushort)(char)o; - return true; - - case TypeCode.SByte: - result = (sbyte)o; - return true; - - case TypeCode.Byte: - result = (byte)o; - return true; - - case TypeCode.Int16: - result = (short)o; - return true; - - case TypeCode.UInt16: - result = (ushort)o; - return true; - - case TypeCode.Int32: - result = (int)o; - return true; - - case TypeCode.UInt32: - result = (uint)o; - return true; - - case TypeCode.Int64: - result = (long)o; - return true; - - case TypeCode.UInt64: - result = (ulong)o; - return true; - - case TypeCode.Single: - result = (float)o; - return true; - - case TypeCode.Double: - result = (double)o; - return true; - } - - result = double.NaN; - return false; - } - - /// - /// Write a value - /// - /// The ctor arg type, field type, or property type - /// The value to write - void WriteElem(TypeSig argType, CAArgument value) { - if (argType is null) { - helper.Error("Custom attribute: Arg type is null"); - argType = value.Type; - if (argType is null) - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - TypeSig underlyingType; - ITypeDefOrRef tdr; - switch (argType.ElementType) { - case ElementType.Boolean: - if (!VerifyTypeAndValue(value, ElementType.Boolean)) - writer.WriteBoolean(ToUInt64(value.Value) != 0); - else - writer.WriteBoolean((bool)value.Value); - break; - - case ElementType.Char: - if (!VerifyTypeAndValue(value, ElementType.Char)) - writer.WriteUInt16((ushort)ToUInt64(value.Value)); - else - writer.WriteUInt16((ushort)(char)value.Value); - break; - - case ElementType.I1: - if (!VerifyTypeAndValue(value, ElementType.I1)) - writer.WriteSByte((sbyte)ToUInt64(value.Value)); - else - writer.WriteSByte((sbyte)value.Value); - break; - - case ElementType.U1: - if (!VerifyTypeAndValue(value, ElementType.U1)) - writer.WriteByte((byte)ToUInt64(value.Value)); - else - writer.WriteByte((byte)value.Value); - break; - - case ElementType.I2: - if (!VerifyTypeAndValue(value, ElementType.I2)) - writer.WriteInt16((short)ToUInt64(value.Value)); - else - writer.WriteInt16((short)value.Value); - break; - - case ElementType.U2: - if (!VerifyTypeAndValue(value, ElementType.U2)) - writer.WriteUInt16((ushort)ToUInt64(value.Value)); - else - writer.WriteUInt16((ushort)value.Value); - break; - - case ElementType.I4: - if (!VerifyTypeAndValue(value, ElementType.I4)) - writer.WriteInt32((int)ToUInt64(value.Value)); - else - writer.WriteInt32((int)value.Value); - break; - - case ElementType.U4: - if (!VerifyTypeAndValue(value, ElementType.U4)) - writer.WriteUInt32((uint)ToUInt64(value.Value)); - else - writer.WriteUInt32((uint)value.Value); - break; - - case ElementType.I8: - if (!VerifyTypeAndValue(value, ElementType.I8)) - writer.WriteInt64((long)ToUInt64(value.Value)); - else - writer.WriteInt64((long)value.Value); - break; - - case ElementType.U8: - if (!VerifyTypeAndValue(value, ElementType.U8)) - writer.WriteUInt64(ToUInt64(value.Value)); - else - writer.WriteUInt64((ulong)value.Value); - break; - - case ElementType.R4: - if (!VerifyTypeAndValue(value, ElementType.R4)) - writer.WriteSingle((float)ToDouble(value.Value)); - else - writer.WriteSingle((float)value.Value); - break; - - case ElementType.R8: - if (!VerifyTypeAndValue(value, ElementType.R8)) - writer.WriteDouble(ToDouble(value.Value)); - else - writer.WriteDouble((double)value.Value); - break; - - case ElementType.String: - if (VerifyTypeAndValue(value, ElementType.String, typeof(UTF8String))) - WriteUTF8String((UTF8String)value.Value); - else if (VerifyTypeAndValue(value, ElementType.String, typeof(string))) - WriteUTF8String((string)value.Value); - else - WriteUTF8String(UTF8String.Empty); - break; - - case ElementType.ValueType: - tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; - underlyingType = GetEnumUnderlyingType(argType); - 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. - } - else - helper.Error("Custom attribute value is not an enum"); - break; - - case ElementType.Class: - tdr = ((TypeDefOrRefSig)argType).TypeDefOrRef; - if (CheckCorLibType(argType, "Type")) { - if (CheckCorLibType(value.Type, "Type")) { - if (value.Value is TypeSig ts) - WriteType(ts); - else if (value.Value is null) - WriteUTF8String(null); - else { - helper.Error("Custom attribute value is not a type"); - WriteUTF8String(UTF8String.Empty); - } - } - else { - helper.Error("Custom attribute value type is not System.Type"); - WriteUTF8String(UTF8String.Empty); - } - break; - } - else if (tdr is TypeRef && TryWriteEnumUnderlyingTypeValue(value.Value)) { - // No error. Assume it's an enum that couldn't be resolved. - break; - } - goto default; - - case ElementType.SZArray: - WriteValue(argType, value); - break; - - case ElementType.Object: - WriteFieldOrPropType(value.Type); - WriteElem(value.Type, value); - break; - - case ElementType.End: - case ElementType.Void: - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.Var: - case ElementType.Array: - case ElementType.GenericInst: - case ElementType.TypedByRef: - case ElementType.ValueArray: - case ElementType.I: - case ElementType.U: - case ElementType.R: - case ElementType.FnPtr: - case ElementType.MVar: - case ElementType.CModReqd: - case ElementType.CModOpt: - case ElementType.Internal: - case ElementType.Module: - case ElementType.Sentinel: - case ElementType.Pinned: - default: - helper.Error("Invalid or unsupported element type in custom attribute"); - break; - } - - recursionCounter.Decrement(); - } - - bool TryWriteEnumUnderlyingTypeValue(object o) { - if (o is null) - return false; - switch (Type.GetTypeCode(o.GetType())) { - 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; - } - - /// - /// Gets the enum's underlying type - /// - /// An enum type - /// The underlying type or null if we couldn't resolve the type ref - static TypeSig GetEnumUnderlyingType(TypeSig type) { - var td = GetEnumTypeDef(type); - if (td is null) - return null; - return td.GetEnumUnderlyingType().RemoveModifiers(); - } - - static TypeDef GetEnumTypeDef(TypeSig type) { - if (type is null) - return null; - var td = GetTypeDef(type); - if (td is null) - return null; - if (!td.IsEnum) - return null; - return td; - } - - /// - /// Converts to a , possibly resolving - /// a - /// - /// The type - /// A or null if we couldn't resolve the - /// or if is a type spec - static TypeDef GetTypeDef(TypeSig type) { - if (type is TypeDefOrRefSig tdr) { - var td = tdr.TypeDef; - if (td is not null) - return td; - - var tr = tdr.TypeRef; - if (tr is not null) - return tr.Resolve(); - } - - return null; - } - - void Write(CANamedArgument namedArg) { - if (namedArg is null) { - helper.Error("Custom attribute named arg is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - if (namedArg.IsProperty) - writer.WriteByte((byte)SerializationType.Property); - else - writer.WriteByte((byte)SerializationType.Field); - - WriteFieldOrPropType(namedArg.Type); - WriteUTF8String(namedArg.Name); - WriteValue(namedArg.Type, namedArg.Argument); - - recursionCounter.Decrement(); - } - - void WriteFieldOrPropType(TypeSig type) { - type = type.RemoveModifiers(); - if (type is null) { - helper.Error("Custom attribute: Field/property type is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - ITypeDefOrRef tdr; - switch (type.ElementType) { - 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.WriteByte((byte)SerializationType.SZArray); - WriteFieldOrPropType(type.Next); - break; - - case ElementType.Class: - tdr = ((TypeDefOrRefSig)type).TypeDefOrRef; - if (CheckCorLibType(type, "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.WriteByte((byte)SerializationType.Enum); - WriteType(tdr); - } - else - goto default; - break; - - case ElementType.ValueType: - tdr = ((TypeDefOrRefSig)type).TypeDefOrRef; - var enumType = GetEnumTypeDef(type); - // If TypeRef => assume it's an enum that couldn't be resolved - if (enumType is not null || tdr is TypeRef) { - writer.WriteByte((byte)SerializationType.Enum); - WriteType(tdr); - } - else { - helper.Error("Custom attribute type doesn't seem to be an enum."); - writer.WriteByte((byte)SerializationType.Enum); - WriteType(tdr); - } - break; - - default: - helper.Error("Custom attribute: Invalid type"); - writer.WriteByte((byte)0xFF); - break; - } - - recursionCounter.Decrement(); - } - - void WriteType(IType type) { - if (type is null) { - helper.Error("Custom attribute: Type is null"); - WriteUTF8String(UTF8String.Empty); - } - else { - sb.Length = 0; - WriteUTF8String(FullNameFactory.AssemblyQualifiedName(type, helper, sb)); - } - } - - static bool CheckCorLibType(TypeSig ts, string name) { - var tdrs = ts as TypeDefOrRefSig; - if (tdrs is null) - return false; - return CheckCorLibType(tdrs.TypeDefOrRef, name); - } - - static bool CheckCorLibType(ITypeDefOrRef tdr, string name) { - if (tdr is null) - return false; - if (!tdr.DefinitionAssembly.IsCorLib()) - return false; - if (tdr is TypeSpec) - return false; - return tdr.TypeName == name && tdr.Namespace == "System"; - } - - static MethodSig GetMethodSig(ICustomAttributeType ctor) => ctor?.MethodSig; - - void WriteUTF8String(UTF8String s) { - if (s is null || s.Data is null) - writer.WriteByte((byte)0xFF); - else { - writer.WriteCompressedUInt32((uint)s.Data.Length); - writer.WriteBytes(s.Data); - } - } - - /// - public void Dispose() { - if (!disposeStream) - return; - if (outStream is not null) - outStream.Dispose(); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/DataReaderChunk.cs b/Plugins/dnlib/DotNet/Writer/DataReaderChunk.cs deleted file mode 100644 index cf9a20c..0000000 --- a/Plugins/dnlib/DotNet/Writer/DataReaderChunk.cs +++ /dev/null @@ -1,98 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// A chunk - /// - public class DataReaderChunk : IChunk { - FileOffset offset; - RVA rva; - DataReader data; - readonly uint virtualSize; - bool setOffsetCalled; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Constructor - /// - /// The data - public DataReaderChunk(DataReader data) - : this(ref data) { - } - - /// - /// Constructor - /// - /// The data - /// Virtual size of - public DataReaderChunk(DataReader data, uint virtualSize) - : this(ref data, virtualSize) { - } - - /// - /// Constructor - /// - /// The data - internal DataReaderChunk(ref DataReader data) - : this(ref data, (uint)data.Length) { - } - - /// - /// Constructor - /// - /// The data - /// Virtual size of - internal DataReaderChunk(ref DataReader data, uint virtualSize) { - this.data = data; - this.virtualSize = virtualSize; - } - - /// - /// Gets the data reader - /// - public DataReader CreateReader() => data; - - /// - /// Replaces the old data with new data. The new data must be the same size as the old data if - /// has been called. That method gets called after - /// event - /// - /// - public void SetData(DataReader newData) { - if (setOffsetCalled && newData.Length != data.Length) - throw new InvalidOperationException("New data must be the same size as the old data after SetOffset() has been called"); - data = newData; - } - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - setOffsetCalled = true; - } - - /// - public uint GetFileLength() => (uint)data.Length; - - /// - public uint GetVirtualSize() => virtualSize; - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - data.Position = 0; - data.CopyTo(writer); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/DataReaderHeap.cs b/Plugins/dnlib/DotNet/Writer/DataReaderHeap.cs deleted file mode 100644 index 34cfdc2..0000000 --- a/Plugins/dnlib/DotNet/Writer/DataReaderHeap.cs +++ /dev/null @@ -1,51 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.DotNet.MD; -using dnlib.IO; -using dnlib.Protection; - -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.CreateReader(); - Name = stream.Name; - } - - /// - /// Constructor - /// - /// Heap name - /// Heap content - public DataReaderHeap(string name, DataReader heapReader) { - this.heapReader = heapReader; - this.heapReader.Position = 0; - Name = name ?? throw new ArgumentNullException(nameof(name)); - } - - /// - public override uint GetRawLength() => heapReader.Length; - - protected override EncryptionMethod GetEncryptionMethod(IEncryption e) => null; - - /// - protected override void WriteToImpl(DataWriter writer) => heapReader.CopyTo(writer); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/DataWriter.cs b/Plugins/dnlib/DotNet/Writer/DataWriter.cs deleted file mode 100644 index 50a5eb2..0000000 --- a/Plugins/dnlib/DotNet/Writer/DataWriter.cs +++ /dev/null @@ -1,257 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; - -namespace dnlib.DotNet.Writer { - /// - /// Writes data - /// - public sealed class DataWriter { - readonly Stream stream; - readonly byte[] buffer; - const int BUFFER_LEN = 8; - - 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 is 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); - - /// - /// 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; - buffer[1] = (byte)(value >> 8); - stream.Write(buffer, 0, 2); - } - - /// - /// Writes a - /// - /// Value - public void WriteUInt16(ushort value) { - var buffer = this.buffer; - buffer[0] = (byte)value; - buffer[1] = (byte)(value >> 8); - stream.Write(buffer, 0, 2); - } - - /// - /// Writes a - /// - /// Value - public void WriteInt32(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); - } - - /// - /// Writes a - /// - /// Value - public void WriteUInt32(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); - } - - /// - /// Writes a - /// - /// Value - public void WriteInt64(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); - } - - /// - /// Writes a - /// - /// Value - public void WriteUInt64(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); - } - - /// - /// Writes a - /// - /// Value - public unsafe void WriteSingle(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); - } - - /// - /// Writes a - /// - /// Value - public unsafe void WriteDouble(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); - } - - /// - /// 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) { - var stream = this.stream; - 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) { - 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"); - } - - /// - /// Writes a compressed - /// - /// - 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. - 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; - 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"); - } - - /// - /// Gets the size of a compressed , see - /// - /// Value - /// - 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; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/DebugDirectory.cs b/Plugins/dnlib/DotNet/Writer/DebugDirectory.cs deleted file mode 100644 index f8d09fa..0000000 --- a/Plugins/dnlib/DotNet/Writer/DebugDirectory.cs +++ /dev/null @@ -1,174 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Pdb; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Debug directory entry - /// - public sealed class DebugDirectoryEntry { - /// - /// Gets the header - /// - public IMAGE_DEBUG_DIRECTORY DebugDirectory; - - /// - /// Gets the data - /// - public readonly IChunk Chunk; - - /// - /// Constructor - /// - /// Data - public DebugDirectoryEntry(IChunk chunk) => Chunk = chunk; - } - - /// - /// Debug directory chunk - /// - public sealed class DebugDirectory : IReuseChunk { - /// Default debug directory alignment - public const uint DEFAULT_DEBUGDIRECTORY_ALIGNMENT = 4; - 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; - - /// - public RVA RVA => rva; - - /// - /// Constructor - /// - public DebugDirectory() => entries = new List(); - - /// - /// Adds data - /// - /// Data - /// - public DebugDirectoryEntry Add(byte[] data) => Add(new ByteArrayChunk(data)); - - /// - /// Adds data - /// - /// 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; - } - - /// - /// 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) - return false; - - isReadonly = true; - return true; - } - - /// - public void SetOffset(FileOffset offset, RVA rva) { - isReadonly = true; - this.offset = offset; - this.rva = rva; - - 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; - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - uint offset = 0; - foreach (var entry in entries) { - 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); - 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; - } - - foreach (var entry in entries) { - WriteAlign(writer, ref offset); - entry.Chunk.VerifyWriteTo(writer); - offset += entry.Chunk.GetFileLength(); - } - } - - static void WriteAlign(DataWriter writer, ref uint offs) { - uint align = Utils.AlignUp(offs, DEFAULT_DEBUGDIRECTORY_ALIGNMENT) - offs; - offs += align; - writer.WriteZeroes((int)align); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/DeclSecurityWriter.cs b/Plugins/dnlib/DotNet/Writer/DeclSecurityWriter.cs deleted file mode 100644 index 8624d9e..0000000 --- a/Plugins/dnlib/DotNet/Writer/DeclSecurityWriter.cs +++ /dev/null @@ -1,111 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; - -namespace dnlib.DotNet.Writer { - /// - /// Writes DeclSecurity blobs - /// - public readonly struct DeclSecurityWriter : ICustomAttributeWriterHelper { - readonly ModuleDef module; - readonly IWriterError helper; - readonly DataWriterContext context; - readonly bool optimizeCustomAttributeSerializedTypeNames; - - /// - /// Creates a DeclSecurity blob from - /// - /// Owner module - /// List of s - /// Helps this class - /// A DeclSecurity blob - public static byte[] Write(ModuleDef module, IList secAttrs, IWriterError helper) => - Write(module, secAttrs, helper, false); - - /// - /// 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, bool optimizeCustomAttributeSerializedTypeNames, DataWriterContext context) { - this.module = module; - this.helper = helper; - this.context = context; - this.optimizeCustomAttributeSerializedTypeNames = optimizeCustomAttributeSerializedTypeNames; - } - - byte[] Write(IList secAttrs) { - if (secAttrs is null) - secAttrs = Array2.Empty(); - - var xml = DeclSecurity.GetNet1xXmlStringInternal(secAttrs); - if (xml is not null) - return WriteFormat1(xml); - return WriteFormat2(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)'.'); - WriteCompressedUInt32(writer, (uint)secAttrs.Count); - - int count = secAttrs.Count; - for (int i = 0; i < count; i++) { - var sa = secAttrs[i]; - if (sa is 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 is null) { - helper.Error("SecurityAttribute attribute type is null"); - fqn = string.Empty; - } - else { - sb.Length = 0; - fqn = FullNameFactory.AssemblyQualifiedName(attrType, null, sb); - } - Write(writer, fqn); - - var namedArgsBlob = context is 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.WriteBytes(namedArgsBlob); - } - - return stream.ToArray(); - } - - 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, optimizeCustomAttributeSerializedTypeNames); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/Extensions.cs b/Plugins/dnlib/DotNet/Writer/Extensions.cs deleted file mode 100644 index d28bc84..0000000 --- a/Plugins/dnlib/DotNet/Writer/Extensions.cs +++ /dev/null @@ -1,22 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// Extension methods - /// - static partial class Extensions { - /// - /// Write zeros - /// - /// this - /// Number of zeros - public static void WriteZeroes(this DataWriter writer, int count) { - while (count >= 8) { - writer.WriteUInt64(0); - count -= 8; - } - for (int i = 0; i < count; i++) - writer.WriteByte(0); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/GuidHeap.cs b/Plugins/dnlib/DotNet/Writer/GuidHeap.cs deleted file mode 100644 index 7e9db44..0000000 --- a/Plugins/dnlib/DotNet/Writer/GuidHeap.cs +++ /dev/null @@ -1,74 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.Protection; - -namespace dnlib.DotNet.Writer { - /// - /// #GUID heap - /// - public sealed class GuidHeap : HeapBase, IOffsetHeap { - readonly Dictionary guids = new Dictionary(); - Dictionary userRawData; - - /// - public override string Name => "#GUID"; - - /// - /// Adds a guid to the #GUID heap - /// - /// The guid - /// The index of the guid in the #GUID heap - public uint Add(Guid? guid) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #GUID when it's read-only"); - if (guid is null) - return 0; - - if (guids.TryGetValue(guid.Value, out uint index)) - return index; - - index = (uint)guids.Count + 1; - guids.Add(guid.Value, index); - return index; - } - - /// - public override uint GetRawLength() => (uint)guids.Count * 16; - - protected override EncryptionMethod GetEncryptionMethod(IEncryption e) => null; - - /// - protected override void WriteToImpl(DataWriter writer) { - uint offset = 0; - foreach (var kv in guids) { - if (userRawData is null || !userRawData.TryGetValue(offset, out var rawData)) - rawData = kv.Key.ToByteArray(); - writer.WriteBytes(rawData); - offset += 16; - } - } - - /// - public int GetRawDataSize(Guid data) => 16; - - /// - public void SetRawData(uint offset, byte[] rawData) { - if (rawData is null || rawData.Length != 16) - throw new ArgumentException("Invalid size of GUID raw data"); - if (userRawData is null) - userRawData = new Dictionary(); - userRawData[offset] = rawData; - } - - /// - public IEnumerable> GetAllRawData() { - uint offset = 0; - foreach (var kv in guids) { - yield return new KeyValuePair(offset, kv.Key.ToByteArray()); - offset += 16; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/Hasher.cs b/Plugins/dnlib/DotNet/Writer/Hasher.cs deleted file mode 100644 index ddef929..0000000 --- a/Plugins/dnlib/DotNet/Writer/Hasher.cs +++ /dev/null @@ -1,73 +0,0 @@ -// 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) => - 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) => - // https://github.com/dotnet/corefx/blob/master/src/System.Reflection.Metadata/specs/PE-COFF.md#pdb-checksum-debug-directory-entry-type-19 - 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) { - 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)) { - 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/Plugins/dnlib/DotNet/Writer/HeapBase.cs b/Plugins/dnlib/DotNet/Writer/HeapBase.cs deleted file mode 100644 index e85fb9a..0000000 --- a/Plugins/dnlib/DotNet/Writer/HeapBase.cs +++ /dev/null @@ -1,88 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.PE; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// Base class of most heaps - /// - public abstract class HeapBase : IHeap { - internal const uint ALIGNMENT = 4; - FileOffset offset; - RVA rva; - - /// - /// true if has been called - /// - protected bool isReadOnly; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - public abstract string Name { get; } - - /// - public bool IsEmpty => GetRawLength() <= 1; - - /// - /// true if offsets require 4 bytes instead of 2 bytes. - /// - public bool IsBig => GetFileLength() > 0xFFFF; - - /// - public void SetReadOnly() => isReadOnly = true; - - /// - 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 - } - - /// - public uint GetFileLength() => Utils.AlignUp(GetRawLength(), ALIGNMENT); - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - /// Gets the raw length of the heap - /// - /// Raw length of the heap - public abstract uint GetRawLength(); - - - - private void WriteTo0(DataWriter writer) { - WriteToImpl(writer); - writer.WriteZeroes((int)(Utils.AlignUp(GetRawLength(), ALIGNMENT) - GetRawLength())); - } - - protected abstract EncryptionMethod GetEncryptionMethod(IEncryption e); - - /// - public void WriteTo(DataWriter writer) { - EncryptionUtil.WriteWithEncIfNeed(writer, WriteTo0, this.GetEncryptionMethod, EncryptionContext.BigSegmentSize); - } - - /// - /// Writes all data to at its current location. - /// - /// Destination - protected abstract void WriteToImpl(DataWriter writer); - - /// - public override string ToString() => Name; - } -} diff --git a/Plugins/dnlib/DotNet/Writer/IChunk.cs b/Plugins/dnlib/DotNet/Writer/IChunk.cs deleted file mode 100644 index 061321a..0000000 --- a/Plugins/dnlib/DotNet/Writer/IChunk.cs +++ /dev/null @@ -1,115 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.IO; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Data that gets written to the file - /// - public interface IChunk { - /// - /// Gets the file offset. This is valid only after has been called. - /// - FileOffset FileOffset { get; } - - /// - /// Gets the RVA. This is valid only after has been called. - /// - RVA RVA { get; } - - /// - /// Called when the file offset and RVA are known - /// - /// File offset of this chunk - /// RVA of this chunk - void SetOffset(FileOffset offset, RVA rva); - - /// - /// Gets the raw file length of this chunk. Must only be called after - /// has been called. - /// - /// Length of this chunk - uint GetFileLength(); - - /// - /// Gets the virtual size of this chunk. Must only be called after - /// has been called. - /// - /// 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. - /// You cannot assume that 's file position is the same as this - /// chunk's file position. - /// - /// Destination - void WriteTo(DataWriter 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 - /// - /// Original RVA of data - /// Size of the original location - /// - bool CanReuse(RVA origRva, uint origSize); - } - - public static partial class Extensions { - /// - /// Writes all data to and verifies that all bytes were written - /// - /// this - /// Destination - /// Not all bytes were written - public static void VerifyWriteTo(this IChunk chunk, DataWriter writer) { - long pos = writer.Position; - // 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 (writer.Position - pos != chunk.GetFileLength()) - VerifyWriteToThrow(chunk); - } - - static void VerifyWriteToThrow(IChunk chunk) => - throw new IOException($"Did not write all bytes: {chunk.GetType().FullName}"); - - /// - /// Writes a data directory - /// - /// Writer - /// The data - internal static void WriteDataDirectory(this DataWriter writer, IChunk chunk) { - if (chunk is null || chunk.GetVirtualSize() == 0) - writer.WriteUInt64(0); - else { - writer.WriteUInt32((uint)chunk.RVA); - writer.WriteUInt32(chunk.GetVirtualSize()); - } - } - - internal static void WriteDebugDirectory(this DataWriter writer, DebugDirectory chunk) { - if (chunk is null || chunk.GetVirtualSize() == 0) - writer.WriteUInt64(0); - else { - writer.WriteUInt32((uint)chunk.RVA); - writer.WriteUInt32((uint)(chunk.Count * DebugDirectory.HEADER_SIZE)); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/IHeap.cs b/Plugins/dnlib/DotNet/Writer/IHeap.cs deleted file mode 100644 index b75e075..0000000 --- a/Plugins/dnlib/DotNet/Writer/IHeap.cs +++ /dev/null @@ -1,23 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// .NET Heap interface - /// - public interface IHeap : IChunk { - /// - /// Gets the name of the heap - /// - string Name { get; } - - /// - /// Checks whether the heap is empty - /// - bool IsEmpty { get; } - - /// - /// Called when the heap should be set to read-only mode - /// - void SetReadOnly(); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/IOffsetHeap.cs b/Plugins/dnlib/DotNet/Writer/IOffsetHeap.cs deleted file mode 100644 index 3c104dc..0000000 --- a/Plugins/dnlib/DotNet/Writer/IOffsetHeap.cs +++ /dev/null @@ -1,34 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.DotNet.Writer { - /// - /// Interface to get and set raw heap data. Implemented by the offset heaps: #Strings, - /// #GUID, #Blob, and #US. - /// - /// Type of cooked data - public interface IOffsetHeap { - /// - /// Gets the size of the data as raw data when written to the heap - /// - /// The data - /// Size of the data as raw data when written to the heap - int GetRawDataSize(TValue data); - - /// - /// Overrides what value should be written to the heap. - /// - /// Offset of value. Must match an offset returned by - /// - /// The new raw data. The size must match the raw size exactly. - void SetRawData(uint offset, byte[] rawData); - - /// - /// Gets all inserted raw data and their offsets. The returned array - /// is owned by the caller. - /// - /// An enumerable of all raw data and their offsets - IEnumerable> GetAllRawData(); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/IWriterError.cs b/Plugins/dnlib/DotNet/Writer/IWriterError.cs deleted file mode 100644 index c6e3005..0000000 --- a/Plugins/dnlib/DotNet/Writer/IWriterError.cs +++ /dev/null @@ -1,46 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// 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 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 - 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); - } - - 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/Plugins/dnlib/DotNet/Writer/ImageCor20Header.cs b/Plugins/dnlib/DotNet/Writer/ImageCor20Header.cs deleted file mode 100644 index 154c3fa..0000000 --- a/Plugins/dnlib/DotNet/Writer/ImageCor20Header.cs +++ /dev/null @@ -1,135 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.PE; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Writer { - /// - /// Options to - /// - public sealed class Cor20HeaderOptions { - /// - /// Default major runtime version - /// - public const ushort DEFAULT_MAJOR_RT_VER = 2; - - /// - /// Default minor runtime version - /// - public const ushort DEFAULT_MINOR_RT_VER = 5; - - /// - /// Major runtime version - /// - public ushort? MajorRuntimeVersion; - - /// - /// Minor runtime version - /// - public ushort? MinorRuntimeVersion; - - /// - /// Flags - /// - public ComImageFlags? Flags; - - /// - /// Entry point or null. Either a Method/File token or an RVA. - /// - public uint? EntryPoint; - - /// - /// Default constructor - /// - public Cor20HeaderOptions() { - } - - /// - /// Constructor - /// - /// Flags - public Cor20HeaderOptions(ComImageFlags flags) => Flags = flags; - - /// - /// Constructor - /// - /// Major runtime version (default is ) - /// Minor runtime version (default is ) - /// Flags - public Cor20HeaderOptions(ushort major, ushort minor, ComImageFlags flags) { - MajorRuntimeVersion = major; - MinorRuntimeVersion = minor; - Flags = flags; - } - } - - /// - /// .NET header - /// - public sealed class ImageCor20Header : IChunk { - FileOffset offset; - RVA rva; - Cor20HeaderOptions options; - - /// - /// Gets/sets the - /// - public Metadata Metadata { get; set; } - - /// - /// Gets/sets the .NET resources - /// - public NetResources NetResources { get; set; } - - /// - /// Gets/sets the strong name signature - /// - public StrongNameSignature StrongNameSignature { get; set; } - - internal IChunk VtableFixups { get; set; } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Constructor - /// - /// Options - public ImageCor20Header(Cor20HeaderOptions options) => this.options = options; - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - } - - /// - public uint GetFileLength() => 0x48; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - 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.WriteUInt32((uint)(options.Flags ?? ComImageFlags.ILOnly)); - writer.WriteUInt32(options.EntryPoint ?? 0); - writer.WriteDataDirectory(NetResources); - writer.WriteDataDirectory(StrongNameSignature); - writer.WriteDataDirectory(null); // Code manager table - writer.WriteDataDirectory(VtableFixups); - writer.WriteDataDirectory(null); // Export address table jumps - writer.WriteDataDirectory(null); // Managed native header - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ImportAddressTable.cs b/Plugins/dnlib/DotNet/Writer/ImportAddressTable.cs deleted file mode 100644 index d789e78..0000000 --- a/Plugins/dnlib/DotNet/Writer/ImportAddressTable.cs +++ /dev/null @@ -1,67 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Import address table chunk - /// - public sealed class ImportAddressTable : IChunk { - readonly bool is64bit; - FileOffset offset; - RVA rva; - - /// - /// Gets/sets the - /// - public ImportDirectory ImportDirectory { get; set; } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => 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; - this.rva = rva; - } - - /// - public uint GetFileLength() { - if (!Enable) - return 0; - return is64bit ? 16U : 8; - } - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - if (!Enable) - return; - if (is64bit) { - writer.WriteUInt64((ulong)(uint)ImportDirectory.CorXxxMainRVA); - writer.WriteUInt64(0); - } - else { - writer.WriteUInt32((uint)ImportDirectory.CorXxxMainRVA); - writer.WriteInt32(0); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ImportDirectory.cs b/Plugins/dnlib/DotNet/Writer/ImportDirectory.cs deleted file mode 100644 index 23fe2b9..0000000 --- a/Plugins/dnlib/DotNet/Writer/ImportDirectory.cs +++ /dev/null @@ -1,141 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Text; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Import directory chunk - /// - public sealed class ImportDirectory : IChunk { - readonly bool is64bit; - FileOffset offset; - RVA rva; - bool isExeFile; - uint length; - RVA importLookupTableRVA; - RVA corXxxMainRVA; - RVA dllToImportRVA; - int stringsPadding; - string dllToImport; - string entryPointName; - - /// - /// Gets/sets the - /// - public ImportAddressTable ImportAddressTable { get; set; } - - /// - /// Gets the RVA of _CorDllMain/_CorExeMain in the import lookup table - /// - public RVA CorXxxMainRVA => corXxxMainRVA; - - /// - /// Gets RVA of _CorExeMain/_CorDllMain in the IAT - /// - public RVA IatCorXxxMainRVA => ImportAddressTable.RVA; - - /// - /// Gets/sets a value indicating whether this is a EXE or a DLL file - /// - public bool IsExeFile { - get => isExeFile; - set => isExeFile = value; - } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - 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; - - /// - /// 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; - this.rva = rva; - - length = 0x28; - importLookupTableRVA = rva + length; - length += is64bit ? 16U : 8; - - stringsPadding = (int)(rva.AlignUp(STRINGS_ALIGNMENT) - rva); - length += (uint)stringsPadding; - corXxxMainRVA = rva + length; - length += 2 + (uint)EntryPointName.Length + 1; - dllToImportRVA = rva + length; - length += (uint)DllToImport.Length + 1; - length++; - } - - /// - public uint GetFileLength() { - if (!Enable) - return 0; - return length; - } - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - if (!Enable) - return; - writer.WriteUInt32((uint)importLookupTableRVA); - writer.WriteInt32(0); // DateTimeStamp - writer.WriteInt32(0); // ForwarderChain - writer.WriteUInt32((uint)dllToImportRVA); // Name - writer.WriteUInt32((uint)ImportAddressTable.RVA); - writer.WriteUInt64(0); - writer.WriteUInt64(0); - writer.WriteInt32(0); - - // ImportLookupTable - if (is64bit) { - writer.WriteUInt64((ulong)(uint)corXxxMainRVA); - writer.WriteUInt64(0); - } - else { - writer.WriteUInt32((uint)corXxxMainRVA); - writer.WriteInt32(0); - } - - writer.WriteZeroes(stringsPadding); - writer.WriteUInt16(0); - writer.WriteBytes(Encoding.UTF8.GetBytes(EntryPointName + "\0")); - writer.WriteBytes(Encoding.UTF8.GetBytes(DllToImport + "\0")); - - writer.WriteByte(0); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MDTable.cs b/Plugins/dnlib/DotNet/Writer/MDTable.cs deleted file mode 100644 index 0f9f356..0000000 --- a/Plugins/dnlib/DotNet/Writer/MDTable.cs +++ /dev/null @@ -1,161 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Writer { - /// - /// MD table interface - /// - public interface IMDTable { - /// - /// Gets the table type - /// - Table Table { get; } - - /// - /// true if the table is empty - /// - bool IsEmpty { get; } - - /// - /// Gets the number of rows in this table - /// - int Rows { get; } - - /// - /// Gets/sets a value indicating whether it's sorted - /// - bool IsSorted { get; set; } - - /// - /// true if has been called - /// - bool IsReadOnly { get; } - - /// - /// Gets/sets the - /// - TableInfo TableInfo { get; set; } - - /// - /// Called when the table can't be modified any more - /// - void SetReadOnly(); - } - - /// - /// Creates rows in a table. Rows can optionally be shared to create a compact table. - /// - /// The raw row type - public sealed class MDTable : IMDTable where TRow : struct { - readonly Table table; - readonly Dictionary cachedDict; - readonly List cached; - TableInfo tableInfo; - bool isSorted; - bool isReadOnly; - - /// - public Table Table => table; - - /// - public bool IsEmpty => cached.Count == 0; - - /// - public int Rows => cached.Count; - - /// - public bool IsSorted { - get => isSorted; - set => isSorted = value; - } - - /// - public bool IsReadOnly => isReadOnly; - - /// - public TableInfo TableInfo { - get => tableInfo; - set => tableInfo = value; - } - - /// - /// Gets the value with rid - /// - /// The row ID - public TRow this[uint rid] { - get => cached[(int)rid - 1]; - set => cached[(int)rid - 1] = value; - } - - /// - /// Constructor - /// - /// The table type - /// Equality comparer - public MDTable(Table table, IEqualityComparer equalityComparer) { - this.table = table; - cachedDict = new Dictionary(equalityComparer); - cached = new List(); - } - - /// - public void SetReadOnly() => isReadOnly = true; - - /// - /// Adds a row. If the row already exists, returns a rid to the existing one, else - /// it's created and a new rid is returned. - /// - /// The row. It's now owned by us and must NOT be modified by the caller. - /// The RID (row ID) of the row - public uint Add(TRow row) { - if (isReadOnly) - 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); - } - - /// - /// Creates a new row even if this row already exists. - /// - /// The row. It's now owned by us and must NOT be modified by the caller. - /// The RID (row ID) of the row - public uint Create(TRow row) { - if (isReadOnly) - 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; - cached.Add(row); - return rid; - } - - /// - /// Re-adds all added rows. Should be called if rows have been modified after being - /// inserted. - /// - public void ReAddRows() { - if (isReadOnly) - 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; - var row = cached[i]; - if (!cachedDict.ContainsKey(row)) - cachedDict[row] = rid; - } - } - - /// - /// Reset the table. - /// - public void Reset() { - if (isReadOnly) - throw new ModuleWriterException($"Trying to modify table {table} after it's been set to read-only"); - cachedDict.Clear(); - cached.Clear(); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MDTableWriter.cs b/Plugins/dnlib/DotNet/Writer/MDTableWriter.cs deleted file mode 100644 index 3a3bd27..0000000 --- a/Plugins/dnlib/DotNet/Writer/MDTableWriter.cs +++ /dev/null @@ -1,995 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.DotNet.MD; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// Writes s - /// - public static class MDTableWriter { - /// - /// Writes a Module table - /// - /// Writer - /// Metadata - /// 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]; - var columns3 = columns[3]; - var columns4 = columns[4]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Generation); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.Mvid); - columns3.Write24(writer, row.EncId); - columns4.Write24(writer, row.EncBaseId); - } - } - - /// - /// Writes a TypeRef table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.ResolutionScope); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, stringsHeap.GetOffset(row.Namespace)); - } - } - - /// - /// Writes a TypeDef table - /// - /// Writer - /// Metadata - /// 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]; - var columns3 = columns[3]; - var columns4 = columns[4]; - var columns5 = columns[5]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - EncryptionUtil.WriteWithNotSegmentEncIfNeed(writer, w => { - w.WriteUInt32(row.Flags); - columns1.Write24(w, stringsHeap.GetOffset(row.Name)); - columns2.Write24(w, stringsHeap.GetOffset(row.Namespace)); - columns3.Write24(w, row.Extends); - columns4.Write24(w, row.FieldList); - columns5.Write24(w, row.MethodList); - }, enc => enc.LazyTableEnc); - //writer.WriteUInt32(row.Flags); - //columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - //columns2.Write24(writer, stringsHeap.GetOffset(row.Namespace)); - //columns3.Write24(writer, row.Extends); - //columns4.Write24(writer, row.FieldList); - //columns5.Write24(writer, row.MethodList); - } - } - - /// - /// Writes a FieldPtr table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Field); - } - } - - /// - /// Writes a Field table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Flags); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.Signature); - } - } - - /// - /// Writes a MethodPtr table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Method); - } - } - - /// - /// Writes a Method table - /// - /// Writer - /// Metadata - /// 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]; - var columns5 = columns[5]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.RVA); - writer.WriteUInt16(row.ImplFlags); - writer.WriteUInt16(row.Flags); - columns3.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns4.Write24(writer, row.Signature); - columns5.Write24(writer, row.ParamList); - } - } - - /// - /// Writes a ParamPtr table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Param); - } - } - - /// - /// Writes a Param table - /// - /// Writer - /// Metadata - /// 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; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Flags); - writer.WriteUInt16(row.Sequence); - columns2.Write24(writer, stringsHeap.GetOffset(row.Name)); - } - } - - /// - /// Writes a InterfaceImpl table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Class); - columns1.Write24(writer, row.Interface); - } - } - - /// - /// Writes a MemberRef table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Class); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.Signature); - } - } - - /// - /// Writes a Constant table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteByte(row.Type); - writer.WriteByte(row.Padding); - columns2.Write24(writer, row.Parent); - columns3.Write24(writer, row.Value); - } - } - - /// - /// Writes a CustomAttribute table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.Type); - columns2.Write24(writer, row.Value); - } - } - - /// - /// Writes a FieldMarshal table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.NativeType); - } - } - - /// - /// Writes a DeclSecurity table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteInt16(row.Action); - columns1.Write24(writer, row.Parent); - columns2.Write24(writer, row.PermissionSet); - } - } - - /// - /// Writes a ClassLayout table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.PackingSize); - writer.WriteUInt32(row.ClassSize); - columns2.Write24(writer, row.Parent); - } - } - - /// - /// Writes a FieldLayout table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.OffSet); - columns1.Write24(writer, row.Field); - } - } - - /// - /// Writes a StandAloneSig table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Signature); - } - } - - /// - /// Writes a EventMap table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.EventList); - } - } - - /// - /// Writes a EventPtr table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Event); - } - } - - /// - /// Writes a Event table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.EventFlags); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.EventType); - } - } - - /// - /// Writes a PropertyMap table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.PropertyList); - } - } - - /// - /// Writes a PropertyPtr table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Property); - } - } - - /// - /// Writes a Property table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.PropFlags); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.Type); - } - } - - /// - /// Writes a MethodSemantics table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Semantic); - columns1.Write24(writer, row.Method); - columns2.Write24(writer, row.Association); - } - } - - /// - /// Writes a MethodImpl table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Class); - columns1.Write24(writer, row.MethodBody); - columns2.Write24(writer, row.MethodDeclaration); - } - } - - /// - /// Writes a ModuleRef table - /// - /// Writer - /// Metadata - /// 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; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, stringsHeap.GetOffset(row.Name)); - } - } - - /// - /// Writes a TypeSpec table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Signature); - } - } - - /// - /// Writes a ImplMap table - /// - /// Writer - /// Metadata - /// 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]; - var columns3 = columns[3]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.MappingFlags); - columns1.Write24(writer, row.MemberForwarded); - columns2.Write24(writer, stringsHeap.GetOffset(row.ImportName)); - columns3.Write24(writer, row.ImportScope); - } - } - - /// - /// Writes a FieldRVA table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.RVA); - columns1.Write24(writer, row.Field); - } - } - - /// - /// Writes a ENCLog table - /// - /// Writer - /// Metadata - /// 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.WriteUInt32(row.Token); - writer.WriteUInt32(row.FuncCode); - } - } - - /// - /// Writes a ENCMap table - /// - /// Writer - /// Metadata - /// 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.WriteUInt32(row.Token); - } - } - - /// - /// Writes a Assembly table - /// - /// Writer - /// Metadata - /// 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]; - var columns8 = columns[8]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.HashAlgId); - writer.WriteUInt16(row.MajorVersion); - writer.WriteUInt16(row.MinorVersion); - writer.WriteUInt16(row.BuildNumber); - writer.WriteUInt16(row.RevisionNumber); - writer.WriteUInt32(row.Flags); - columns6.Write24(writer, row.PublicKey); - columns7.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns8.Write24(writer, stringsHeap.GetOffset(row.Locale)); - } - } - - /// - /// Writes a AssemblyProcessor table - /// - /// Writer - /// Metadata - /// 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.WriteUInt32(row.Processor); - } - } - - /// - /// Writes a AssemblyOS table - /// - /// Writer - /// Metadata - /// 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.WriteUInt32(row.OSPlatformId); - writer.WriteUInt32(row.OSMajorVersion); - writer.WriteUInt32(row.OSMinorVersion); - } - } - - /// - /// Writes a AssemblyRef table - /// - /// Writer - /// Metadata - /// 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]; - var columns7 = columns[7]; - var columns8 = columns[8]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.MajorVersion); - writer.WriteUInt16(row.MinorVersion); - writer.WriteUInt16(row.BuildNumber); - writer.WriteUInt16(row.RevisionNumber); - writer.WriteUInt32(row.Flags); - columns5.Write24(writer, row.PublicKeyOrToken); - columns6.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns7.Write24(writer, stringsHeap.GetOffset(row.Locale)); - columns8.Write24(writer, row.HashValue); - } - } - - /// - /// Writes a AssemblyRefProcessor table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.Processor); - columns1.Write24(writer, row.AssemblyRef); - } - } - - /// - /// Writes a AssemblyRefOS table - /// - /// Writer - /// Metadata - /// 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++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.OSPlatformId); - writer.WriteUInt32(row.OSMajorVersion); - writer.WriteUInt32(row.OSMinorVersion); - columns3.Write24(writer, row.AssemblyRef); - } - } - - /// - /// Writes a File table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.Flags); - columns1.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns2.Write24(writer, row.HashValue); - } - } - - /// - /// Writes a ExportedType table - /// - /// Writer - /// Metadata - /// 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]; - var columns4 = columns[4]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.Flags); - writer.WriteUInt32(row.TypeDefId); - columns2.Write24(writer, stringsHeap.GetOffset(row.TypeName)); - columns3.Write24(writer, stringsHeap.GetOffset(row.TypeNamespace)); - columns4.Write24(writer, row.Implementation); - } - } - - /// - /// Writes a ManifestResource table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt32(row.Offset); - writer.WriteUInt32(row.Flags); - columns2.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns3.Write24(writer, row.Implementation); - } - } - - /// - /// Writes a NestedClass table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.NestedClass); - columns1.Write24(writer, row.EnclosingClass); - } - } - - /// - /// Writes a GenericParam table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - if (columns.Length >= 5) { - var columns4 = columns[4]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Number); - writer.WriteUInt16(row.Flags); - columns2.Write24(writer, row.Owner); - columns3.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns4.Write24(writer, row.Kind); - } - } - else { - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Number); - writer.WriteUInt16(row.Flags); - columns2.Write24(writer, row.Owner); - columns3.Write24(writer, stringsHeap.GetOffset(row.Name)); - } - } - } - - /// - /// Writes a MethodSpec table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Method); - columns1.Write24(writer, row.Instantiation); - } - } - - /// - /// Writes a GenericParamConstraint table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Owner); - columns1.Write24(writer, row.Constraint); - } - } - - /// - /// Writes a Document table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - var columns3 = columns[3]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Name); - columns1.Write24(writer, row.HashAlgorithm); - columns2.Write24(writer, row.Hash); - columns3.Write24(writer, row.Language); - } - } - - /// - /// Writes a MethodDebugInformation table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Document); - columns1.Write24(writer, row.SequencePoints); - } - } - - /// - /// Writes a LocalScope table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - var columns3 = columns[3]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Method); - columns1.Write24(writer, row.ImportScope); - columns2.Write24(writer, row.VariableList); - columns3.Write24(writer, row.ConstantList); - writer.WriteUInt32(row.StartOffset); - writer.WriteUInt32(row.Length); - } - } - - /// - /// Writes a LocalVariable table - /// - /// Writer - /// Metadata - /// 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; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - writer.WriteUInt16(row.Attributes); - writer.WriteUInt16(row.Index); - columns2.Write24(writer, stringsHeap.GetOffset(row.Name)); - } - } - - /// - /// Writes a LocalConstant table - /// - /// Writer - /// Metadata - /// 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]; - var stringsHeap = metadata.StringsHeap; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, stringsHeap.GetOffset(row.Name)); - columns1.Write24(writer, row.Signature); - } - } - - /// - /// Writes a ImportScope table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.Imports); - } - } - - /// - /// Writes a StateMachineMethod table - /// - /// Writer - /// Metadata - /// 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]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.MoveNextMethod); - columns1.Write24(writer, row.KickoffMethod); - } - } - - /// - /// Writes a CustomDebugInformation table - /// - /// Writer - /// Metadata - /// 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]; - var columns2 = columns[2]; - for (int i = 0; i < table.Rows; i++) { - var row = table[(uint)i + 1]; - columns0.Write24(writer, row.Parent); - columns1.Write24(writer, row.Kind); - columns2.Write24(writer, row.Value); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ManagedExportsWriter.cs b/Plugins/dnlib/DotNet/Writer/ManagedExportsWriter.cs deleted file mode 100644 index 6455b2c..0000000 --- a/Plugins/dnlib/DotNet/Writer/ManagedExportsWriter.cs +++ /dev/null @@ -1,531 +0,0 @@ -// 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 Action logError; - readonly VtableFixupsChunk vtableFixups; - readonly StubsChunk stubsChunk; - readonly SdataChunk sdataChunk; - readonly ExportDir exportDir; - readonly List vtables; - readonly List allMethodInfos; - readonly List sortedOrdinalMethodInfos; - readonly List sortedNameMethodInfos; - readonly CpuArch cpuArch; - uint exportDirOffset; - - bool Is64Bit => machine.Is64Bit(); - 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 => 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(); - public uint CalculateAlignment() => 0; - void IChunk.WriteTo(DataWriter writer) => throw new NotSupportedException(); - } - - sealed class VtableFixupsChunk : IChunk { - readonly ManagedExportsWriter owner; - FileOffset offset; - RVA rva; - internal uint length; - 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() => length; - public uint GetVirtualSize() => GetFileLength(); - public uint CalculateAlignment() => 0; - public void WriteTo(DataWriter writer) => owner.WriteVtableFixups(writer); - } - - sealed class StubsChunk : IChunk { - readonly ManagedExportsWriter owner; - FileOffset offset; - RVA rva; - internal uint length; - 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() => length; - public uint GetVirtualSize() => GetFileLength(); - public uint CalculateAlignment() => 0; - public void WriteTo(DataWriter writer) => owner.WriteStubs(writer); - } - - sealed class SdataChunk : IChunk { - readonly ManagedExportsWriter owner; - FileOffset offset; - RVA rva; - internal uint length; - 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() => length; - public uint GetVirtualSize() => GetFileLength(); - public uint CalculateAlignment() => 0; - public void WriteTo(DataWriter writer) => owner.WriteSdata(writer); - } - - public ManagedExportsWriter(string moduleName, Machine machine, RelocDirectory relocDirectory, Metadata metadata, PEHeaders peHeaders, Action 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(); - sortedOrdinalMethodInfos = new List(); - sortedNameMethodInfos = 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 is not 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 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; - } - 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}", new object[] { methods.Count }); - return; - } - - Initialize(methods, timestamp); - } - - sealed class MethodInfo { - public readonly MethodDef Method; - public readonly uint StubChunkOffset; - public int FunctionIndex; - public uint ManagedVtblOffset; - public uint NameOffset; - public int NameIndex; - public byte[] NameBytes; - public MethodInfo(MethodDef method, uint stubChunkOffset) { - Method = method; - StubChunkOffset = stubChunkOffset; - } - } - - 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.Bit64 : VTableFlags.Bit32; - uint stubOffset = 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 is not null); - if (exportInfo is 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; - - 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)); - var info = new MethodInfo(method, stubOffset + stubCodeOffset); - allMethodInfos.Add(info); - list[list.Count - 1].Methods.Add(info); - stubOffset = (stubOffset + stubSize + stubAlignment - 1) & ~(stubAlignment - 1); - } - - 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 => methodNamesCount; - - readonly 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; - return GetOffset(name, out var bytes); - } - - uint GetOffset(string name, out byte[] bytes) { - if (nameOffsets.TryGetValue(name, out var 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 is not 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(DataWriter writer) { - foreach (var name in names) - writer.WriteBytes(name); - } - - public uint[] GetMethodNameOffsets() => 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 DataWriter(stream); - - // Write all vtables (referenced from the .text section) - Debug.Assert((writer.Position & 7) == 0); - foreach (var vtbl in vtables) { - vtbl.SdataChunkOffset = (uint)writer.Position; - foreach (var info in vtbl.Methods) { - info.ManagedVtblOffset = (uint)writer.Position; - writer.WriteUInt32(0x06000000 + metadata.GetRid(info.Method)); - if ((vtbl.Flags & VTableFlags.Bit64) != 0) - writer.WriteUInt32(0); - } - } - - var namesBlob = new NamesBlob(1 == 2); - int nameIndex = 0; - bool error = false; - foreach (var info in allMethodInfos) { - var exportInfo = info.Method.ExportInfo; - var name = exportInfo.Name; - if (name is null) { - if (exportInfo.Ordinal is not null) { - sortedOrdinalMethodInfos.Add(info); - continue; - } - name = info.Method.Name; - } - if (string.IsNullOrEmpty(name)) { - error = true; - logError("Exported method name is null or empty, method: {0} (0x{1:X8})", new object[] { info.Method, info.Method.MDToken.Raw }); - continue; - } - info.NameOffset = namesBlob.GetMethodNameOffset(name, out info.NameBytes); - info.NameIndex = nameIndex++; - sortedNameMethodInfos.Add(info); - } - Debug.Assert(error || sortedOrdinalMethodInfos.Count + sortedNameMethodInfos.Count == allMethodInfos.Count); - sdataBytesInfo.MethodNameOffsets = namesBlob.GetMethodNameOffsets(); - Debug.Assert(sortedNameMethodInfos.Count == sdataBytesInfo.MethodNameOffsets.Length); - sdataBytesInfo.moduleNameOffset = namesBlob.GetOtherNameOffset(moduleName); - - sortedOrdinalMethodInfos.Sort((a, b) => a.Method.ExportInfo.Ordinal.Value.CompareTo(b.Method.ExportInfo.Ordinal.Value)); - sortedNameMethodInfos.Sort((a, b) => CompareTo(a.NameBytes, b.NameBytes)); - - int ordinalBase, nextFreeOrdinal; - if (sortedOrdinalMethodInfos.Count == 0) { - ordinalBase = 0; - nextFreeOrdinal = 0; - } - else { - ordinalBase = sortedOrdinalMethodInfos[0].Method.ExportInfo.Ordinal.Value; - nextFreeOrdinal = sortedOrdinalMethodInfos[sortedOrdinalMethodInfos.Count - 1].Method.ExportInfo.Ordinal.Value + 1; - } - int nameFuncBaseIndex = nextFreeOrdinal - ordinalBase; - int lastFuncIndex = 0; - for (int i = 0; i < sortedOrdinalMethodInfos.Count; i++) { - int index = sortedOrdinalMethodInfos[i].Method.ExportInfo.Ordinal.Value - ordinalBase; - sortedOrdinalMethodInfos[i].FunctionIndex = index; - lastFuncIndex = index; - } - for (int i = 0; i < sortedNameMethodInfos.Count; i++) { - lastFuncIndex = nameFuncBaseIndex + i; - sortedNameMethodInfos[i].FunctionIndex = lastFuncIndex; - } - int funcSize = lastFuncIndex + 1; - if (funcSize > 0x10000) { - logError("Exported function array is too big", Array2.Empty()); - return; - } - - // Write IMAGE_EXPORT_DIRECTORY - Debug.Assert((writer.Position & 3) == 0); - exportDirOffset = (uint)writer.Position; - writer.WriteUInt32(0); // Characteristics - writer.WriteUInt32(timestamp); - writer.WriteUInt32(0); // MajorVersion, MinorVersion - sdataBytesInfo.exportDirModuleNameStreamOffset = (uint)writer.Position; - 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.WriteUInt32(0); // AddressOfFunctions - writer.WriteUInt32(0); // AddressOfNames - writer.WriteUInt32(0); // AddressOfNameOrdinals - - sdataBytesInfo.addressOfFunctionsStreamOffset = (uint)writer.Position; - writer.WriteZeroes(funcSize * 4); - sdataBytesInfo.addressOfNamesStreamOffset = (uint)writer.Position; - writer.WriteZeroes(sdataBytesInfo.MethodNameOffsets.Length * 4); - sdataBytesInfo.addressOfNameOrdinalsStreamOffset = (uint)writer.Position; - writer.WriteZeroes(sdataBytesInfo.MethodNameOffsets.Length * 2); - sdataBytesInfo.namesBlobStreamOffset = (uint)writer.Position; - namesBlob.Write(writer); - - sdataBytesInfo.Data = stream.ToArray(); - } - - void WriteSdata(DataWriter writer) { - if (sdataBytesInfo.Data is null) - return; - PatchSdataBytesBlob(); - writer.WriteBytes(sdataBytesInfo.Data); - } - - void PatchSdataBytesBlob() { - uint rva = (uint)sdataChunk.RVA; - uint namesBaseOffset = rva + sdataBytesInfo.namesBlobStreamOffset; - - var writer = new DataWriter(new MemoryStream(sdataBytesInfo.Data)); - - writer.Position = sdataBytesInfo.exportDirModuleNameStreamOffset; - writer.WriteUInt32(namesBaseOffset + sdataBytesInfo.moduleNameOffset); - - writer.Position = sdataBytesInfo.exportDirAddressOfFunctionsStreamOffset; - writer.WriteUInt32(rva + sdataBytesInfo.addressOfFunctionsStreamOffset); // AddressOfFunctions - if (sdataBytesInfo.MethodNameOffsets.Length != 0) { - writer.WriteUInt32(rva + sdataBytesInfo.addressOfNamesStreamOffset); // AddressOfNames - writer.WriteUInt32(rva + sdataBytesInfo.addressOfNameOrdinalsStreamOffset); // AddressOfNameOrdinals - } - - uint funcBaseRva = (uint)stubsChunk.RVA; - writer.Position = sdataBytesInfo.addressOfFunctionsStreamOffset; - int currentFuncIndex = 0; - foreach (var info in sortedOrdinalMethodInfos) { - int zeroes = info.FunctionIndex - currentFuncIndex; - if (zeroes < 0) - throw new InvalidOperationException(); - while (zeroes-- > 0) - 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.WriteUInt32(funcBaseRva + info.StubChunkOffset); - } - - var nameOffsets = sdataBytesInfo.MethodNameOffsets; - if (nameOffsets.Length != 0) { - writer.Position = sdataBytesInfo.addressOfNamesStreamOffset; - foreach (var info in sortedNameMethodInfos) - writer.WriteUInt32(namesBaseOffset + nameOffsets[info.NameIndex]); - - writer.Position = sdataBytesInfo.addressOfNameOrdinalsStreamOffset; - foreach (var info in sortedNameMethodInfos) - writer.WriteUInt16((ushort)info.FunctionIndex); - } - } - - void WriteVtableFixups(DataWriter writer) { - if (vtables.Count == 0) - return; - - foreach (var vtbl in vtables) { - Debug.Assert(vtbl.Methods.Count <= ushort.MaxValue); - writer.WriteUInt32((uint)sdataChunk.RVA + vtbl.SdataChunkOffset); - writer.WriteUInt16((ushort)vtbl.Methods.Count); - writer.WriteUInt16((ushort)vtbl.Flags); - } - } - - void WriteStubs(DataWriter writer) { - if (vtables.Count == 0) - return; - if (cpuArch is 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.Position; - cpuArch.WriteStub(stubType, writer, imageBase, stubsBaseRva + currentOffset, vtblBaseRva + info.ManagedVtblOffset); - Debug.Assert(pos + stubSize == writer.Position, "The full stub wasn't written"); - if (pos + stubSize != writer.Position) - throw new InvalidOperationException(); - if (zeroes != 0) - writer.WriteZeroes(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/Plugins/dnlib/DotNet/Writer/MarshalBlobWriter.cs b/Plugins/dnlib/DotNet/Writer/MarshalBlobWriter.cs deleted file mode 100644 index df5ead8..0000000 --- a/Plugins/dnlib/DotNet/Writer/MarshalBlobWriter.cs +++ /dev/null @@ -1,151 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; - -namespace dnlib.DotNet.Writer { - /// - /// Writes field marshal blobs - /// - public readonly struct MarshalBlobWriter : IDisposable, IFullNameFactoryHelper { - readonly ModuleDef module; - readonly MemoryStream outStream; - readonly DataWriter writer; - readonly IWriterError helper; - readonly bool optimizeCustomAttributeSerializedTypeNames; - - /// - /// Creates a field marshal blob from - /// - /// Owner module - /// Marshal type - /// Helps this class - /// A field marshal blob or null if is - /// null - 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, bool optimizeCustomAttributeSerializedTypeNames) { - this.module = module; - outStream = new MemoryStream(); - writer = new DataWriter(outStream); - this.helper = helper; - this.optimizeCustomAttributeSerializedTypeNames = optimizeCustomAttributeSerializedTypeNames; - } - - byte[] Write(MarshalType marshalType) { - if (marshalType is null) - return null; - - var type = marshalType.NativeType; - if (type != NativeType.RawBlob) { - if ((uint)type > byte.MaxValue) - helper.Error("Invalid MarshalType.NativeType"); - writer.WriteByte((byte)type); - } - bool canWrite = true; - switch (type) { - case NativeType.FixedSysString: - var fixedSysString = (FixedSysStringMarshalType)marshalType; - if (fixedSysString.IsSizeValid) - WriteCompressedUInt32((uint)fixedSysString.Size); - break; - - case NativeType.SafeArray: - var safeArray = (SafeArrayMarshalType)marshalType; - if (UpdateCanWrite(safeArray.IsVariantTypeValid, "VariantType", ref canWrite)) - WriteCompressedUInt32((uint)safeArray.VariantType); - if (UpdateCanWrite(safeArray.IsUserDefinedSubTypeValid, "UserDefinedSubType", ref canWrite)) - Write(safeArray.UserDefinedSubType.AssemblyQualifiedName); - break; - - case NativeType.FixedArray: - var fixedArray = (FixedArrayMarshalType)marshalType; - if (UpdateCanWrite(fixedArray.IsSizeValid, "Size", ref canWrite)) - WriteCompressedUInt32((uint)fixedArray.Size); - if (UpdateCanWrite(fixedArray.IsElementTypeValid, "ElementType", ref canWrite)) - WriteCompressedUInt32((uint)fixedArray.ElementType); - break; - - case NativeType.Array: - var array = (ArrayMarshalType)marshalType; - if (UpdateCanWrite(array.IsElementTypeValid, "ElementType", ref canWrite)) - WriteCompressedUInt32((uint)array.ElementType); - if (UpdateCanWrite(array.IsParamNumberValid, "ParamNumber", ref canWrite)) - WriteCompressedUInt32((uint)array.ParamNumber); - if (UpdateCanWrite(array.IsSizeValid, "Size", ref canWrite)) - WriteCompressedUInt32((uint)array.Size); - if (UpdateCanWrite(array.IsFlagsValid, "Flags", ref canWrite)) - WriteCompressedUInt32((uint)array.Flags); - break; - - case NativeType.CustomMarshaler: - var custMarshaler = (CustomMarshalType)marshalType; - Write(custMarshaler.Guid); - Write(custMarshaler.NativeTypeName); - var cm = custMarshaler.CustomMarshaler; - var cmName = cm is null ? string.Empty : FullNameFactory.AssemblyQualifiedName(cm, this); - Write(cmName); - Write(custMarshaler.Cookie); - break; - - case NativeType.IUnknown: - case NativeType.IDispatch: - case NativeType.IntF: - var iface = (InterfaceMarshalType)marshalType; - if (iface.IsIidParamIndexValid) - WriteCompressedUInt32((uint)iface.IidParamIndex); - break; - - case NativeType.RawBlob: - var data = ((RawMarshalType)marshalType).Data; - if (data is not null) - writer.WriteBytes(data); - break; - - default: - break; - } - - return outStream.ToArray(); - } - - bool UpdateCanWrite(bool isValid, string field, ref bool canWriteMore) { - if (!canWriteMore) { - if (isValid) - helper.Error2("MarshalType field {0} is valid even though a previous field was invalid.", field); - return canWriteMore; - } - - if (!isValid) - canWriteMore = false; - - return canWriteMore; - } - - uint WriteCompressedUInt32(uint value) => writer.WriteCompressedUInt32(helper, value); - - void Write(UTF8String s) => writer.Write(helper, s); - - /// - public void Dispose() => outStream?.Dispose(); - - bool IFullNameFactoryHelper.MustUseAssemblyName(IType type) => - FullNameFactory.MustUseAssemblyName(module, type, optimizeCustomAttributeSerializedTypeNames); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MaxStackCalculator.cs b/Plugins/dnlib/DotNet/Writer/MaxStackCalculator.cs deleted file mode 100644 index ea745e2..0000000 --- a/Plugins/dnlib/DotNet/Writer/MaxStackCalculator.cs +++ /dev/null @@ -1,177 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet.Writer { - /// - /// Calculates max stack usage by using a simple pass over all instructions. This value - /// can be placed in the fat method header's MaxStack field. - /// - public struct MaxStackCalculator { - IList instructions; - IList exceptionHandlers; - readonly Dictionary stackHeights; - bool hasError; - int currentMaxStack; - - /// - /// Gets max stack value - /// - /// All instructions - /// All exception handlers - /// Max stack value - public static uint GetMaxStack(IList instructions, IList exceptionHandlers) { - new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out uint maxStack); - return maxStack; - } - - /// - /// Gets max stack value - /// - /// All instructions - /// All 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) => - new MaxStackCalculator(instructions, exceptionHandlers).Calculate(out maxStack); - - internal static MaxStackCalculator Create() => new MaxStackCalculator(true); - - MaxStackCalculator(bool dummy) { - instructions = null; - exceptionHandlers = null; - stackHeights = new Dictionary(); - hasError = false; - currentMaxStack = 0; - } - - MaxStackCalculator(IList instructions, IList exceptionHandlers) { - this.instructions = instructions; - this.exceptionHandlers = exceptionHandlers; - stackHeights = new Dictionary(); - hasError = false; - currentMaxStack = 0; - } - - internal void Reset(IList instructions, IList exceptionHandlers) { - this.instructions = instructions; - this.exceptionHandlers = exceptionHandlers; - stackHeights.Clear(); - hasError = false; - currentMaxStack = 0; - } - - internal bool Calculate(out uint maxStack) { - var exceptionHandlers = this.exceptionHandlers; - var stackHeights = this.stackHeights; - for (int i = 0; i < exceptionHandlers.Count; i++) { - var eh = exceptionHandlers[i]; - if (eh is null) - continue; - Instruction instr; - if ((instr = eh.TryStart) is not null) - stackHeights[instr] = 0; - if ((instr = eh.FilterStart) is not null) { - stackHeights[instr] = 1; - currentMaxStack = 1; - } - if ((instr = eh.HandlerStart) is not null) { - bool pushed = eh.IsCatch || eh.IsFilter; - if (pushed) { - stackHeights[instr] = 1; - currentMaxStack = 1; - } - else - stackHeights[instr] = 0; - } - } - - int stack = 0; - bool resetStack = false; - var instructions = this.instructions; - for (int i = 0; i < instructions.Count; i++) { - var instr = instructions[i]; - if (instr is null) - continue; - - if (resetStack) { - stackHeights.TryGetValue(instr, out stack); - resetStack = false; - } - stack = WriteStack(instr, stack); - var opCode = instr.OpCode; - var code = opCode.Code; - if (code == Code.Jmp) { - if (stack != 0) - hasError = true; - } - else { - instr.CalculateStackUsage(out int pushes, out int pops); - if (pops == -1) - stack = 0; - else { - stack -= pops; - if (stack < 0) { - hasError = true; - stack = 0; - } - stack += pushes; - } - } - if (stack < 0) { - hasError = true; - stack = 0; - } - - switch (opCode.FlowControl) { - case FlowControl.Branch: - WriteStack(instr.Operand as Instruction, stack); - resetStack = true; - break; - - case FlowControl.Call: - if (code == Code.Jmp) - resetStack = true; - break; - - case FlowControl.Cond_Branch: - if (code == Code.Switch) { - if (instr.Operand is IList targets) { - for (int j = 0; j < targets.Count; j++) - WriteStack(targets[j], stack); - } - } - else - WriteStack(instr.Operand as Instruction, stack); - break; - - case FlowControl.Return: - case FlowControl.Throw: - resetStack = true; - break; - } - } - - maxStack = (uint)currentMaxStack; - return !hasError; - } - - int WriteStack(Instruction instr, int stack) { - if (instr is null) { - hasError = true; - return stack; - } - var stackHeights = this.stackHeights; - if (stackHeights.TryGetValue(instr, out int stack2)) { - if (stack != stack2) - hasError = true; - return stack2; - } - stackHeights[instr] = stack; - if (stack > currentMaxStack) - currentMaxStack = stack; - return stack; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/Metadata.cs b/Plugins/dnlib/DotNet/Writer/Metadata.cs deleted file mode 100644 index 28e874a..0000000 --- a/Plugins/dnlib/DotNet/Writer/Metadata.cs +++ /dev/null @@ -1,3842 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Text; -using dnlib.DotNet.Emit; -using dnlib.DotNet.MD; -using dnlib.DotNet.Pdb; -using dnlib.DotNet.Pdb.Portable; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// flags - /// - [Flags] - public enum MetadataFlags : uint { - /// - /// Preserves all rids in the TypeRef table - /// - PreserveTypeRefRids = 1, - - /// - /// Preserves all rids in the TypeDef table - /// - PreserveTypeDefRids = 2, - - /// - /// Preserves all rids in the Field table - /// - PreserveFieldRids = 4, - - /// - /// Preserves all rids in the Method table - /// - PreserveMethodRids = 8, - - /// - /// Preserves all rids in the Param table - /// - PreserveParamRids = 0x10, - - /// - /// Preserves all rids in the MemberRef table - /// - PreserveMemberRefRids = 0x20, - - /// - /// Preserves all rids in the StandAloneSig table - /// - PreserveStandAloneSigRids = 0x40, - - /// - /// Preserves all rids in the Event table - /// - PreserveEventRids = 0x80, - - /// - /// Preserves all rids in the Property table - /// - PreservePropertyRids = 0x100, - - /// - /// Preserves all rids in the TypeSpec table - /// - PreserveTypeSpecRids = 0x200, - - /// - /// Preserves all rids in the MethodSpec table - /// - PreserveMethodSpecRids = 0x400, - - /// - /// Preserves all method rids, i.e., Method, MemberRef and - /// MethodSpec rids. - /// - PreserveAllMethodRids = PreserveMethodRids | PreserveMemberRefRids | PreserveMethodSpecRids, - - /// - /// Preserves all rids in the following tables: TypeRef, TypeDef, - /// Field, Method, Param, MemberRef, StandAloneSig, - /// Event, Property, TypeSpec, MethodSpec - /// - PreserveRids = PreserveTypeRefRids | - PreserveTypeDefRids | - PreserveFieldRids | - PreserveMethodRids | - PreserveParamRids | - PreserveMemberRefRids | - PreserveStandAloneSigRids | - PreserveEventRids | - PreservePropertyRids | - PreserveTypeSpecRids | - PreserveMethodSpecRids, - - /// - /// Preserves all offsets in the #Strings heap (the original #Strings heap will be saved - /// in the new file). Type names, field names, and other non-user strings are stored - /// in the #Strings heap. - /// - PreserveStringsOffsets = 0x800, - - /// - /// Preserves all offsets in the #US heap (the original #US heap will be saved - /// in the new file). User strings (referenced by the ldstr instruction) are stored in - /// the #US heap. - /// - PreserveUSOffsets = 0x1000, - - /// - /// Preserves all offsets in the #Blob heap (the original #Blob heap will be saved - /// in the new file). Custom attributes, signatures and other blobs are stored in the - /// #Blob heap. - /// - PreserveBlobOffsets = 0x2000, - - /// - /// Preserves the extra data that is present after the original signature in the #Blob - /// heap. This extra data shouldn't be present but might be present if an obfuscator - /// has added this extra data and is eg. using it to decrypt stuff. - /// - PreserveExtraSignatureData = 0x4000, - - /// - /// Preserves as much as possible - /// - PreserveAll = PreserveRids | PreserveStringsOffsets | PreserveUSOffsets | - PreserveBlobOffsets | PreserveExtraSignatureData, - - /// - /// The original method body's max stack field should be used and a new one should not - /// be calculated. - /// - KeepOldMaxStack = 0x8000, - - /// - /// Always create the #GUID heap even if it's empty - /// - AlwaysCreateGuidHeap = 0x10000, - - /// - /// Always create the #Strings heap even if it's empty - /// - AlwaysCreateStringsHeap = 0x20000, - - /// - /// Always create the #US heap even if it's empty - /// - AlwaysCreateUSHeap = 0x40000, - - /// - /// Always create the #Blob heap even if it's empty - /// - 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 - /// - RoslynSortInterfaceImpl = 0x100000, - - /// - /// Don't write method bodies - /// - NoMethodBodies = 0x200000, - - /// - /// Don't write .NET resources - /// - NoDotNetResources = 0x400000, - - /// - /// Don't write field data - /// - NoFieldData = 0x800000, - - /// - /// Serialized type names stored in custom attributes are optimized if the types - /// 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). - ///
- OptimizeCustomAttributeSerializedTypeNames = 0x1000000, - } - - /// - /// 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 - /// - public sealed class MetadataOptions { - MetadataHeaderOptions metadataHeaderOptions; - MetadataHeaderOptions debugMetadataHeaderOptions; - TablesHeapOptions tablesHeapOptions; - List customHeaps; - - /// - /// Gets/sets the options. This is never null. - /// - public MetadataHeaderOptions MetadataHeaderOptions { - get => metadataHeaderOptions ??= new MetadataHeaderOptions(); - set => metadataHeaderOptions = value; - } - - /// - /// Gets/sets the debug (portable PDB) options. This is never null. - /// - public MetadataHeaderOptions DebugMetadataHeaderOptions { - get => debugMetadataHeaderOptions ??= MetadataHeaderOptions.CreatePortablePdbV1_0(); - set => debugMetadataHeaderOptions = value; - } - - /// - /// Gets/sets the options. This is never null. - /// - public TablesHeapOptions TablesHeapOptions { - get => tablesHeapOptions ??= new TablesHeapOptions(); - set => tablesHeapOptions = value; - } - - /// - /// Gets/sets the debug (portable PDB) options. This is never null. - /// - public TablesHeapOptions DebugTablesHeapOptions { - get => tablesHeapOptions ??= TablesHeapOptions.CreatePortablePdbV1_0(); - set => tablesHeapOptions = value; - } - - /// - /// Various options - /// - public MetadataFlags Flags; - - /// - /// Extra heaps to add to the metadata. Also see and - /// - public List CustomHeaps => customHeaps ??= new List(); - - /// - /// Raised after all heaps have been added. The caller can sort the list if needed - /// - 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 is null) - throw new ArgumentNullException(nameof(module)); - if (module is ModuleDefMD mod) { - if (addCustomHeaps) { - 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); - 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, 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] = order; - order++; - } - 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 - /// - public MetadataOptions() { - } - - /// - /// Constructor - /// - /// Flags - public MetadataOptions(MetadataFlags flags) => Flags = flags; - - /// - /// Constructor - /// - /// Meta data header options - public MetadataOptions(MetadataHeaderOptions mdhOptions) => metadataHeaderOptions = mdhOptions; - - /// - /// Constructor - /// - /// Meta data header options - /// Flags - public MetadataOptions(MetadataHeaderOptions mdhOptions, MetadataFlags flags) { - Flags = flags; - metadataHeaderOptions = mdhOptions; - } - } - - sealed class DataWriterContext { - public readonly MemoryStream OutStream; - public readonly DataWriter Writer; - public DataWriterContext() { - OutStream = new MemoryStream(); - Writer = new DataWriter(OutStream); - } - } - - /// - /// Portable PDB metadata kind - /// - public enum DebugMetadataKind { - /// - /// No debugging metadata - /// - None, - - /// - /// Standalone / embedded portable PDB metadata - /// - Standalone, - } - - /// - /// Metadata writer event args - /// - public readonly struct MetadataWriterEventArgs { - /// - /// Gets the metadata writer - /// - public Metadata Metadata { get; } - - /// - /// Gets the event - /// - public MetadataEvent Event { get; } - - /// - /// Constructor - /// - /// Writer - /// Event - public MetadataWriterEventArgs(Metadata metadata, MetadataEvent @event) { - Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); - Event = @event; - } - } - - /// - /// Metadata writer progress event args - /// - public readonly struct MetadataProgressEventArgs { - /// - /// 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 - /// - public abstract class Metadata : IReuseChunk, ISignatureWriterHelper, ITokenProvider, ICustomAttributeWriterHelper, IPortablePdbCustomDebugInfoWriterHelper, IWriterError2 { - uint length; - FileOffset offset; - RVA rva; - readonly MetadataOptions options; - ILogger logger; - readonly MetadataErrorContext errorContext; - 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 readonly PdbHeap pdbHeap; - internal readonly TablesHeap tablesHeap; - internal readonly StringsHeap stringsHeap; - internal readonly USHeap usHeap; - internal readonly GuidHeap guidHeap; - internal readonly BlobHeap blobHeap; - internal TypeDef[] allTypeDefs; - internal readonly Rows moduleDefInfos = new Rows(); - internal readonly SortedRows interfaceImplInfos = new SortedRows(); - internal readonly SortedRows hasConstantInfos = new SortedRows(); - internal readonly SortedRows customAttributeInfos = new SortedRows(); - internal readonly SortedRows fieldMarshalInfos = new SortedRows(); - internal readonly SortedRows declSecurityInfos = new SortedRows(); - internal readonly SortedRows classLayoutInfos = new SortedRows(); - internal readonly SortedRows fieldLayoutInfos = new SortedRows(); - internal readonly Rows eventMapInfos = new Rows(); - internal readonly Rows propertyMapInfos = new Rows(); - internal readonly SortedRows methodSemanticsInfos = new SortedRows(); - internal readonly SortedRows methodImplInfos = new SortedRows(); - internal readonly Rows moduleRefInfos = new Rows(); - internal readonly SortedRows implMapInfos = new SortedRows(); - internal readonly SortedRows fieldRVAInfos = new SortedRows(); - internal readonly Rows assemblyInfos = new Rows(); - internal readonly Rows assemblyRefInfos = new Rows(); - internal readonly Rows fileDefInfos = new Rows(); - internal readonly Rows exportedTypeInfos = new Rows(); - internal readonly Rows manifestResourceInfos = new Rows(); - internal readonly SortedRows nestedClassInfos = new SortedRows(); - internal readonly SortedRows genericParamInfos = new SortedRows(); - internal readonly SortedRows genericParamConstraintInfos = new SortedRows(); - internal readonly Dictionary methodToBody = new Dictionary(); - internal readonly Dictionary methodToNativeBody = new Dictionary(); - internal readonly Dictionary embeddedResourceToByteArray = new Dictionary(); - readonly Dictionary fieldToInitialValue = new Dictionary(); - 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(); - readonly List exportedMethods = new List(); - - /// - /// Raised at various times when writing the metadata - /// - public event EventHandler2 MetadataEvent; - - /// - /// Raised when the progress is updated - /// - public event EventHandler2 ProgressUpdated; - - /// - /// Gets/sets the logger - /// - public ILogger Logger { - get => logger; - set => logger = value; - } - - /// - /// Gets the module - /// - public ModuleDef Module => module; - - /// - /// Gets the constants - /// - public UniqueChunkList Constants => constants; - - /// - /// Gets the method body chunks - /// - public MethodBodyChunks MethodBodyChunks => methodBodies; - - /// - /// Gets the .NET resources - /// - public NetResources NetResources => netResources; - - /// - /// Gets the MD header - /// - public MetadataHeader MetadataHeader => metadataHeader; - - /// - /// 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 => 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 => 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 => 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 => 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 => blobHeap; - - /// - /// Gets the #Pdb heap. It's only used if it's portable PDB metadata - /// - public PdbHeap PdbHeap => pdbHeap; - - /// - /// Gets all exported methods - /// - public List ExportedMethods => exportedMethods; - - /// - /// The public key that should be used instead of the one in . - /// - internal byte[] AssemblyPublicKey { get; set; } - - internal sealed class SortedRows where T : class where TRow : struct { - public List infos = new List(); - Dictionary toRid = new Dictionary(); - bool isSorted; - - public struct Info { - public readonly T data; - public /*readonly*/ TRow row; - public Info(T data, ref TRow row) { - this.data = data; - this.row = row; - } - } - - public void Add(T data, TRow row) { - if (isSorted) - throw new ModuleWriterException($"Adding a row after it's been sorted. Table: {row.GetType()}"); - infos.Add(new Info(data, ref row)); - toRid[data] = (uint)toRid.Count + 1; - } - - 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) => - (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) => toRid[data]; - - public bool TryGetRid(T data, out uint rid) { - if (data is null) { - rid = 0; - return false; - } - return toRid.TryGetValue(data, out rid); - } - } - - internal sealed class Rows where T : class { - Dictionary dict = new Dictionary(); - - public int Count => dict.Count; - - public bool TryGetRid(T value, out uint rid) { - if (value is null) { - rid = 0; - return false; - } - return dict.TryGetValue(value, out 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; - } - - /// - /// Creates a instance - /// - /// Module - /// Constants list - /// 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 = null, DebugMetadataKind debugKind = DebugMetadataKind.None) { - 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); - return new NormalMetadata(module, constants, methodBodies, netResources, options, debugKind, false); - } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets the bit - /// - public bool PreserveTypeRefRids => (options.Flags & MetadataFlags.PreserveTypeRefRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveTypeDefRids => (options.Flags & MetadataFlags.PreserveTypeDefRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveFieldRids => (options.Flags & MetadataFlags.PreserveFieldRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveMethodRids => (options.Flags & MetadataFlags.PreserveMethodRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveParamRids => (options.Flags & MetadataFlags.PreserveParamRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveMemberRefRids => (options.Flags & MetadataFlags.PreserveMemberRefRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveStandAloneSigRids => (options.Flags & MetadataFlags.PreserveStandAloneSigRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveEventRids => (options.Flags & MetadataFlags.PreserveEventRids) != 0; - - /// - /// Gets the bit - /// - public bool PreservePropertyRids => (options.Flags & MetadataFlags.PreservePropertyRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveTypeSpecRids => (options.Flags & MetadataFlags.PreserveTypeSpecRids) != 0; - - /// - /// Gets the bit - /// - public bool PreserveMethodSpecRids => (options.Flags & MetadataFlags.PreserveMethodSpecRids) != 0; - - /// - /// Gets/sets the bit - /// - public bool PreserveStringsOffsets { - get => (options.Flags & MetadataFlags.PreserveStringsOffsets) != 0; - set { - if (value) - options.Flags |= MetadataFlags.PreserveStringsOffsets; - else - options.Flags &= ~MetadataFlags.PreserveStringsOffsets; - } - } - - /// - /// Gets/sets the bit - /// - public bool PreserveUSOffsets { - get => (options.Flags & MetadataFlags.PreserveUSOffsets) != 0; - set { - if (value) - options.Flags |= MetadataFlags.PreserveUSOffsets; - else - options.Flags &= ~MetadataFlags.PreserveUSOffsets; - } - } - - /// - /// Gets/sets the bit - /// - public bool PreserveBlobOffsets { - get => (options.Flags & MetadataFlags.PreserveBlobOffsets) != 0; - set { - if (value) - options.Flags |= MetadataFlags.PreserveBlobOffsets; - else - options.Flags &= ~MetadataFlags.PreserveBlobOffsets; - } - } - - /// - /// Gets/sets the bit - /// - public bool PreserveExtraSignatureData { - get => (options.Flags & MetadataFlags.PreserveExtraSignatureData) != 0; - set { - if (value) - options.Flags |= MetadataFlags.PreserveExtraSignatureData; - else - options.Flags &= ~MetadataFlags.PreserveExtraSignatureData; - } - } - - /// - /// Gets/sets the bit - /// - public bool KeepOldMaxStack { - get => (options.Flags & MetadataFlags.KeepOldMaxStack) != 0; - set { - if (value) - options.Flags |= MetadataFlags.KeepOldMaxStack; - else - options.Flags &= ~MetadataFlags.KeepOldMaxStack; - } - } - - /// - /// Gets/sets the bit - /// - public bool AlwaysCreateGuidHeap { - get => (options.Flags & MetadataFlags.AlwaysCreateGuidHeap) != 0; - set { - if (value) - options.Flags |= MetadataFlags.AlwaysCreateGuidHeap; - else - options.Flags &= ~MetadataFlags.AlwaysCreateGuidHeap; - } - } - - /// - /// Gets/sets the bit - /// - public bool AlwaysCreateStringsHeap { - get => (options.Flags & MetadataFlags.AlwaysCreateStringsHeap) != 0; - set { - if (value) - options.Flags |= MetadataFlags.AlwaysCreateStringsHeap; - else - options.Flags &= ~MetadataFlags.AlwaysCreateStringsHeap; - } - } - - /// - /// Gets/sets the bit - /// - public bool AlwaysCreateUSHeap { - get => (options.Flags & MetadataFlags.AlwaysCreateUSHeap) != 0; - set { - if (value) - options.Flags |= MetadataFlags.AlwaysCreateUSHeap; - else - options.Flags &= ~MetadataFlags.AlwaysCreateUSHeap; - } - } - - /// - /// Gets/sets the bit - /// - public bool AlwaysCreateBlobHeap { - get => (options.Flags & MetadataFlags.AlwaysCreateBlobHeap) != 0; - set { - if (value) - options.Flags |= MetadataFlags.AlwaysCreateBlobHeap; - else - options.Flags &= ~MetadataFlags.AlwaysCreateBlobHeap; - } - } - - /// - /// Gets/sets the bit - /// - public bool RoslynSortInterfaceImpl { - get => (options.Flags & MetadataFlags.RoslynSortInterfaceImpl) != 0; - set { - if (value) - options.Flags |= MetadataFlags.RoslynSortInterfaceImpl; - else - options.Flags &= ~MetadataFlags.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; - } - } - - /// - /// 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. - /// - internal bool KeepFieldRVA { get; set; } - - /// - /// Gets the number of methods that will be written. - /// - protected abstract int NumberOfMethods { get; } - - 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(); - 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(); - - errorContext = new MetadataErrorContext(); - - 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(nameof(debugKind)); - } - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(ModuleDef module) { - moduleDefInfos.TryGetRid(module, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(TypeRef tr); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(TypeDef td); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(FieldDef fd); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(MethodDef md); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(ParamDef pd); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(InterfaceImpl ii) { - interfaceImplInfos.TryGetRid(ii, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(MemberRef mr); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetConstantRid(IHasConstant hc) { - hasConstantInfos.TryGetRid(hc, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetCustomAttributeRid(CustomAttribute ca) { - customAttributeInfos.TryGetRid(ca, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetFieldMarshalRid(IHasFieldMarshal hfm) { - fieldMarshalInfos.TryGetRid(hfm, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(DeclSecurity ds) { - declSecurityInfos.TryGetRid(ds, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetClassLayoutRid(TypeDef td) { - classLayoutInfos.TryGetRid(td, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetFieldLayoutRid(FieldDef fd) { - fieldLayoutInfos.TryGetRid(fd, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(StandAloneSig sas); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetEventMapRid(TypeDef td) { - eventMapInfos.TryGetRid(td, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(EventDef ed); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetPropertyMapRid(TypeDef td) { - propertyMapInfos.TryGetRid(td, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(PropertyDef pd); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetMethodSemanticsRid(MethodDef md) { - methodSemanticsInfos.TryGetRid(md, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(ModuleRef mr) { - moduleRefInfos.TryGetRid(mr, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(TypeSpec ts); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetImplMapRid(IMemberForwarded mf) { - implMapInfos.TryGetRid(mf, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetFieldRVARid(FieldDef fd) { - fieldRVAInfos.TryGetRid(fd, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(AssemblyDef asm) { - assemblyInfos.TryGetRid(asm, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(AssemblyRef asmRef) { - assemblyRefInfos.TryGetRid(asmRef, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(FileDef fd) { - fileDefInfos.TryGetRid(fd, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(ExportedType et) { - exportedTypeInfos.TryGetRid(et, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetManifestResourceRid(Resource resource) { - manifestResourceInfos.TryGetRid(resource, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetNestedClassRid(TypeDef td) { - nestedClassInfos.TryGetRid(td, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(GenericParam gp) { - genericParamInfos.TryGetRid(gp, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public abstract uint GetRid(MethodSpec ms); - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(GenericParamConstraint gpc) { - genericParamConstraintInfos.TryGetRid(gpc, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(PdbDocument doc) { - if (debugMetadata is null) - return 0; - debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(PdbScope scope) { - if (debugMetadata is null) - return 0; - debugMetadata.localScopeInfos.TryGetRid(scope, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(PdbLocal local) { - if (debugMetadata is null) - return 0; - debugMetadata.localVariableInfos.TryGetRid(local, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(PdbConstant constant) { - if (debugMetadata is null) - return 0; - - debugMetadata.localConstantInfos.TryGetRid(constant, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetRid(PdbImportScope importScope) { - if (debugMetadata is null) - return 0; - debugMetadata.importScopeInfos.TryGetRid(importScope, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetStateMachineMethodRid(PdbAsyncMethodCustomDebugInfo asyncMethod) { - if (debugMetadata is null) - return 0; - debugMetadata.stateMachineMethodInfos.TryGetRid(asyncMethod, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetStateMachineMethodRid(PdbIteratorMethodCustomDebugInfo iteratorMethod) { - if (debugMetadata is null) - return 0; - debugMetadata.stateMachineMethodInfos.TryGetRid(iteratorMethod, out uint rid); - return rid; - } - - /// - /// Gets the new rid - /// - /// Value - /// Its new rid or 0 - public uint GetCustomDebugInfoRid(PdbCustomDebugInfo cdi) { - if (debugMetadata is null) - return 0; - debugMetadata.customDebugInfos.TryGetRid(cdi, out uint rid); - return rid; - } - - /// - /// Gets the - /// - /// Method - /// The or null if is - /// null or not a method defined in this module. - public MethodBody GetMethodBody(MethodDef md) { - if (md is null) - return null; - methodToBody.TryGetValue(md, out var mb); - return mb; - } - - /// - /// Gets a method's local variable signature token - /// - /// Method - /// Locals sig token or 0 - public uint GetLocalVarSigToken(MethodDef md) => GetMethodBody(md)?.LocalVarSigTok ?? 0; - - /// - /// Gets the where the resource data will be stored - /// - /// Embedded resource - /// A instance or null if - /// is invalid - public DataReaderChunk GetChunk(EmbeddedResource er) { - if (er is null) - return null; - embeddedResourceToByteArray.TryGetValue(er, out var chunk); - return chunk; - } - - /// - /// Gets the where the initial value is stored - /// - /// Field - /// A instance or null if - /// is invalid - public ByteArrayChunk GetInitialValueChunk(FieldDef fd) { - if (fd is null) - return null; - fieldToInitialValue.TryGetValue(fd, out var chunk); - return chunk; - } - - ILogger GetLogger() => logger ?? DummyLogger.ThrowModuleWriterExceptionOnErrorInstance; - - /// - /// Called when an error is detected - /// - /// Error message - /// Optional message arguments - 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) { - 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)); - } - - 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 - /// - public void CreateTables() { - OnMetadataEvent(Writer.MetadataEvent.BeginCreateTables); - - if (module.Types.Count == 0 || module.Types[0] is null) - throw new ModuleWriterException("Missing global type"); - - if (module is ModuleDefMD moduleDefMD) { - if (PreserveStringsOffsets) - stringsHeap.Populate(moduleDefMD.StringsStream); - if (PreserveUSOffsets) - usHeap.Populate(moduleDefMD.USStream); - if (PreserveBlobOffsets) - blobHeap.Populate(moduleDefMD.BlobStream); - } - - Create(); - } - - /// - /// Updates each Method row's RVA column if it has any code - /// - void UpdateMethodRvas() { - foreach (var kv in methodToBody) { - var method = kv.Key; - var body = kv.Value; - uint rid = GetRid(method); - var row = tablesHeap.MethodTable[rid]; - row = new RawMethodRow((uint)body.RVA, row.ImplFlags, row.Flags, row.Name, row.Signature, row.ParamList); - tablesHeap.MethodTable[rid] = row; - } - foreach (var kv in methodToNativeBody) { - var method = kv.Key; - var body = kv.Value; - uint rid = GetRid(method); - var row = tablesHeap.MethodTable[rid]; - row = new RawMethodRow((uint)body.RVA, row.ImplFlags, row.Flags, row.Name, row.Signature, row.ParamList); - tablesHeap.MethodTable[rid] = row; - } - } - - /// - /// Updates the FieldRVA rows - /// - void UpdateFieldRvas() { - foreach (var kv in fieldToInitialValue) { - var field = kv.Key; - var iv = kv.Value; - uint rid = fieldRVAInfos.Rid(field); - var row = tablesHeap.FieldRVATable[rid]; - row = new RawFieldRVARow((uint)iv.RVA, row.Field); - tablesHeap.FieldRVATable[rid] = row; - } - } - - void Create() { - Debug.Assert(!isStandaloneDebugMetadata); - Initialize(); - allTypeDefs = GetAllTypeDefs(); - OnMetadataEvent(Writer.MetadataEvent.AllocateTypeDefRids); - AllocateTypeDefRids(); - OnMetadataEvent(Writer.MetadataEvent.AllocateMemberDefRids); - AllocateMemberDefRids(); - OnMetadataEvent(Writer.MetadataEvent.MemberDefRidsAllocated); - - AddModule(module); - AddPdbDocuments(); - InitializeMethodDebugInformation(); - InitializeTypeDefsAndMemberDefs(); - OnMetadataEvent(Writer.MetadataEvent.MemberDefsInitialized); - - InitializeVTableFixups(); - - AddExportedTypes(); - InitializeEntryPoint(); - if (module.Assembly is not null) - AddAssembly(module.Assembly, AssemblyPublicKey); - - OnMetadataEvent(Writer.MetadataEvent.BeforeSortTables); - SortTables(); - InitializeGenericParamConstraintTable(); - OnMetadataEvent(Writer.MetadataEvent.MostTablesSorted); - - WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos(); - OnMetadataEvent(Writer.MetadataEvent.MemberDefCustomAttributesWritten); - - OnMetadataEvent(Writer.MetadataEvent.BeginAddResources); - AddResources(module.Resources); - OnMetadataEvent(Writer.MetadataEvent.EndAddResources); - - OnMetadataEvent(Writer.MetadataEvent.BeginWriteMethodBodies); - WriteMethodBodies(); - OnMetadataEvent(Writer.MetadataEvent.EndWriteMethodBodies); - - BeforeSortingCustomAttributes(); - InitializeCustomAttributeAndCustomDebugInfoTables(); - OnMetadataEvent(Writer.MetadataEvent.OnAllTablesSorted); - - EverythingInitialized(); - OnMetadataEvent(Writer.MetadataEvent.EndCreateTables); - } - - /// - /// Initializes all TypeDef, Field, Method, Event, - /// Property and Param rows. Other tables that are related to these six - /// tables are also updated. No custom attributes are written yet, though. Method bodies - /// aren't written either. - /// - void InitializeTypeDefsAndMemberDefs() { - int count; - int numTypes = allTypeDefs.Length; - int typeNum = 0; - int notifyNum = 0; - const int numNotifyEvents = 5; - 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++; - notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); - } - - 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 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); - AddInterfaceImpls(typeRid, type.Interfaces); - AddClassLayout(type); - AddNestedType(type, type.DeclaringType); - - var fields = type.Fields; - count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (field is null) { - 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; - AddFieldLayout(field); - AddFieldMarshal(new MDToken(Table.Field, rid), field); - AddFieldRVA(field); - AddImplMap(new MDToken(Table.Field, rid), field); - AddConstant(new MDToken(Table.Field, rid), field); - } - - var methods = type.Methods; - count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method is null) { - Error("Method is null"); - continue; - } - using var __ = errorContext.SetSource(method); - if (method.ExportInfo is not null) - ExportedMethods.Add(method); - uint rid = GetRid(method); - var row = tablesHeap.MethodTable[rid]; - row = new RawMethodRow(row.RVA, (ushort)method.ImplAttributes, (ushort)method.Attributes, stringsHeap.Add(method.Name), GetSignature(method.Signature), row.ParamList); - tablesHeap.MethodTable[rid] = row; - AddGenericParams(new MDToken(Table.Method, rid), method.GenericParameters); - AddDeclSecurities(new MDToken(Table.Method, rid), method.DeclSecurities); - AddImplMap(new MDToken(Table.Method, rid), method); - AddMethodImpls(method, method.Overrides); - var paramDefs = method.ParamDefs; - int count2 = paramDefs.Count; - for (int j = 0; j < count2; j++) { - var pd = paramDefs[j]; - if (pd is null) { - Error("Param is null"); - continue; - } - uint pdRid = GetRid(pd); - var pdRow = new RawParamRow((ushort)pd.Attributes, pd.Sequence, stringsHeap.Add(pd.Name)); - tablesHeap.ParamTable[pdRid] = pdRow; - AddConstant(new MDToken(Table.Param, pdRid), pd); - AddFieldMarshal(new MDToken(Table.Param, pdRid), pd); - } - } - - var events = type.Events; - count = events.Count; - for (int i = 0; i < count; i++) { - var evt = events[i]; - if (evt is null) { - 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; - AddMethodSemantics(evt); - } - - var properties = type.Properties; - count = properties.Count; - for (int i = 0; i < count; i++) { - var prop = properties[i]; - if (prop is null) { - 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; - AddConstant(new MDToken(Table.Property, rid), prop); - AddMethodSemantics(prop); - } - } - } - - /// - /// Writes TypeDef, Field, Method, Event, - /// Property and Param custom attributes and custom debug infos. - /// - void WriteTypeDefAndMemberDefCustomAttributesAndCustomDebugInfos() { - int count; - int numTypes = allTypeDefs.Length; - int typeNum = 0; - int notifyNum = 0; - const int numNotifyEvents = 5; - int notifyAfter = numTypes / numNotifyEvents; - - 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++; - notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); - } - - if (type is null) - continue; - if (type.HasCustomAttributes || type.HasCustomDebugInfos) { - rid = GetRid(type); - AddCustomAttributes(Table.TypeDef, rid, type); - AddCustomDebugInformationList(Table.TypeDef, rid, type); - } - - var fields = type.Fields; - count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (field is null) - continue; - if (field.HasCustomAttributes || field.HasCustomDebugInfos) { - rid = GetRid(field); - AddCustomAttributes(Table.Field, rid, field); - AddCustomDebugInformationList(Table.Field, rid, field); - } - } - - var methods = type.Methods; - count = methods.Count; - for (int i = 0; i < count; i++) { - 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); - // Method custom debug info is added later when writing method bodies - } - var paramDefs = method.ParamDefs; - int count2 = paramDefs.Count; - for (int j = 0; j < count2; j++) { - var pd = paramDefs[j]; - if (pd is null) - continue; - if (pd.HasCustomAttributes || pd.HasCustomDebugInfos) { - rid = GetRid(pd); - AddCustomAttributes(Table.Param, rid, pd); - AddCustomDebugInformationList(Table.Param, rid, pd); - } - } - } - var events = type.Events; - count = events.Count; - for (int i = 0; i < count; i++) { - var evt = events[i]; - if (evt is null) - continue; - if (evt.HasCustomAttributes || evt.HasCustomDebugInfos) { - rid = GetRid(evt); - AddCustomAttributes(Table.Event, rid, evt); - AddCustomDebugInformationList(Table.Event, rid, evt); - } - } - var properties = type.Properties; - count = properties.Count; - for (int i = 0; i < count; i++) { - var prop = properties[i]; - if (prop is null) - continue; - if (prop.HasCustomAttributes || prop.HasCustomDebugInfos) { - rid = GetRid(prop); - AddCustomAttributes(Table.Property, rid, prop); - AddCustomDebugInformationList(Table.Property, rid, prop); - } - } - } - } - - /// - /// Adds the tokens of all methods in all vtables, if any - /// - void InitializeVTableFixups() { - var fixups = module.VTableFixups; - 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"); - continue; - } - foreach (var method in vtable) { - if (method is null) - continue; - AddMDTokenProvider(method); - } - } - } - - void AddExportedTypes() { - using var _ = errorContext.SetSource("exported types"); - var exportedTypes = module.ExportedTypes; - int count = exportedTypes.Count; - for (int i = 0; i < count; i++) - AddExportedType(exportedTypes[i]); - } - - /// - /// Adds the entry point. It's only needed if it's a since if it's - /// a , it will have already been added. - /// - void InitializeEntryPoint() { - using var _ = errorContext.SetSource("entry point"); - if (module.ManagedEntryPoint is FileDef epFile) - AddFile(epFile); - } - - /// - /// Sorts all unsorted tables except GenericParamConstraint and CustomAttribute - /// - void SortTables() { - classLayoutInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); - hasConstantInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); - declSecurityInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); - fieldLayoutInfos.Sort((a, b) => a.row.Field.CompareTo(b.row.Field)); - fieldMarshalInfos.Sort((a, b) => a.row.Parent.CompareTo(b.row.Parent)); - fieldRVAInfos.Sort((a, b) => a.row.Field.CompareTo(b.row.Field)); - implMapInfos.Sort((a, b) => a.row.MemberForwarded.CompareTo(b.row.MemberForwarded)); - methodImplInfos.Sort((a, b) => a.row.Class.CompareTo(b.row.Class)); - methodSemanticsInfos.Sort((a, b)=> a.row.Association.CompareTo(b.row.Association)); - nestedClassInfos.Sort((a, b) => a.row.NestedClass.CompareTo(b.row.NestedClass)); - genericParamInfos.Sort((a, b) => { - if (a.row.Owner != b.row.Owner) - return a.row.Owner.CompareTo(b.row.Owner); - return a.row.Number.CompareTo(b.row.Number); - }); - interfaceImplInfos.Sort((a, b) => a.row.Class.CompareTo(b.row.Class)); - - tablesHeap.ClassLayoutTable.IsSorted = true; - tablesHeap.ConstantTable.IsSorted = true; - tablesHeap.DeclSecurityTable.IsSorted = true; - tablesHeap.FieldLayoutTable.IsSorted = true; - tablesHeap.FieldMarshalTable.IsSorted = true; - tablesHeap.FieldRVATable.IsSorted = true; - tablesHeap.GenericParamTable.IsSorted = true; - tablesHeap.ImplMapTable.IsSorted = true; - tablesHeap.InterfaceImplTable.IsSorted = true; - tablesHeap.MethodImplTable.IsSorted = true; - tablesHeap.MethodSemanticsTable.IsSorted = true; - tablesHeap.NestedClassTable.IsSorted = true; - - // These two are also sorted - tablesHeap.EventMapTable.IsSorted = true; - tablesHeap.PropertyMapTable.IsSorted = true; - - foreach (var info in classLayoutInfos.infos) tablesHeap.ClassLayoutTable.Create(info.row); - foreach (var info in hasConstantInfos.infos) tablesHeap.ConstantTable.Create(info.row); - foreach (var info in declSecurityInfos.infos) tablesHeap.DeclSecurityTable.Create(info.row); - foreach (var info in fieldLayoutInfos.infos) tablesHeap.FieldLayoutTable.Create(info.row); - foreach (var info in fieldMarshalInfos.infos) tablesHeap.FieldMarshalTable.Create(info.row); - foreach (var info in fieldRVAInfos.infos) tablesHeap.FieldRVATable.Create(info.row); - foreach (var info in genericParamInfos.infos) tablesHeap.GenericParamTable.Create(info.row); - foreach (var info in implMapInfos.infos) tablesHeap.ImplMapTable.Create(info.row); - foreach (var info in interfaceImplInfos.infos) tablesHeap.InterfaceImplTable.Create(info.row); - foreach (var info in methodImplInfos.infos) tablesHeap.MethodImplTable.Create(info.row); - 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) { - 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) { - 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) { - 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); - } - } - } - - /// - /// Initializes the GenericParamConstraint table - /// - 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; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method is null) - continue; - using var __ = errorContext.SetSource(method); - AddGenericParamConstraints(method.GenericParameters); - } - } - genericParamConstraintInfos.Sort((a, b) => a.row.Owner.CompareTo(b.row.Owner)); - tablesHeap.GenericParamConstraintTable.IsSorted = true; - foreach (var info in genericParamConstraintInfos.infos) - tablesHeap.GenericParamConstraintTable.Create(info.row); - foreach (var info in genericParamConstraintInfos.infos) { - 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); - } - } - } - - /// - /// Inserts all custom attribute / custom debug info rows in the tables and sort them - /// - 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 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) - 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); - if (NoMethodBodies) - return; - int numMethods = NumberOfMethods; - int methodNum = 0; - int notifyNum = 0; - // Writing method bodies is the most expensive part and takes the longest - 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; - if (debugMetadata is 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) { - 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++; - notifyAfter = (int)((double)numMethods / numNotifyEvents * (notifyNum + 1)); - } - - uint localVarSigTok = 0; - - 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.Write(); - 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; - } - } - else { - var nativeBody = method.NativeBody; - if (nativeBody is not null) - methodToNativeBody[method] = nativeBody; - else if (method.MethodBody is not null) - Error("Unsupported method body"); - } - - if (debugMetadata is not null) { - uint rid = GetRid(method); - - if (cilBody is not null) { - var pdbMethod = cilBody.PdbMethod; - if (pdbMethod is not null) { - // 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, - }); - } - } - } - } - - // Always add CDIs even if it has no managed method body - AddCustomDebugInformationList(method, rid, localVarSigTok); - } - } - } - if (debugMetadata is not 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) { - uint localScopeRid = (uint)debugMetadata.localScopeInfos.infos.Count + 1; - var row = new RawLocalScopeRow(info.MethodRid, AddImportScope(info.Scope.ImportScope), - (uint)debugMetadata.tablesHeap.LocalVariableTable.Rows + 1, - (uint)debugMetadata.tablesHeap.LocalConstantTable.Rows + 1, - info.ScopeStart, info.ScopeLength); - debugMetadata.localScopeInfos.Add(info.Scope, row); - var variables = info.Scope.Variables; - int count = variables.Count; - for (int i = 0; i < count; i++) { - var local = variables[i]; - AddLocalVariable(local); - } - 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); - } - - debugMetadata.tablesHeap.LocalScopeTable.IsSorted = true; - foreach (var info in debugMetadata.localScopeInfos.infos) - debugMetadata.tablesHeap.LocalScopeTable.Create(info.row); - } - if (serializerMethodContext is not null) - Free(ref serializerMethodContext); - } - - 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 is not null) - return false; - if (scope.Scopes.Count != 0) - return false; - if (scope.CustomDebugInfos.Count != 0) - return false; - if (scope.End is not 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 - /// - /// Any type - /// 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 is null) - return true; - int count = list.Count; - for (int i = 0; i < count; i++) { - if (list[i] is not null) - return false; - } - return true; - } - - /// - public MDToken GetToken(object o) { - if (o is IMDTokenProvider tp) - return new MDToken(tp.MDToken.Table, AddMDTokenProvider(tp)); - - if (o is string s) - return new MDToken((Table)0x70, usHeap.Add(s)); - - if (o is MethodSig methodSig) - return new MDToken(Table.StandAloneSig, AddStandAloneSig(methodSig, methodSig.OriginalToken)); - - if (o is FieldSig fieldSig) - return new MDToken(Table.StandAloneSig, AddStandAloneSig(fieldSig, 0)); - - if (o is null) - Error("Instruction operand is null"); - else - Error("Invalid instruction operand"); - return new MDToken((Table)0xFF, 0x00FFFFFF); - } - - /// - public virtual MDToken GetToken(IList locals, uint origToken) { - if (locals is null || locals.Count == 0) - return new MDToken((Table)0, 0); - - 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); - } - - /// - /// Adds a - /// - /// Method signature - /// Original StandAloneSig token or 0 if none - /// Its new rid - protected virtual uint AddStandAloneSig(MethodSig methodSig, uint origToken) { - if (methodSig is null) { - Error("StandAloneSig: MethodSig is null"); - return 0; - } - - var row = new RawStandAloneSigRow(GetSignature(methodSig)); - uint rid = tablesHeap.StandAloneSigTable.Add(row); - //TODO: Add custom attributes - //TODO: Add custom debug infos - 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 is null) { - Error("StandAloneSig: FieldSig is null"); - return 0; - } - - var row = new RawStandAloneSigRow(GetSignature(fieldSig)); - uint rid = tablesHeap.StandAloneSigTable.Add(row); - //TODO: Add custom attributes - //TODO: Add custom debug infos - return rid; - } - - uint AddMDTokenProvider(IMDTokenProvider tp) { - if (tp is not null) { - switch (tp.MDToken.Table) { - case Table.Module: - return AddModule((ModuleDef)tp); - - case Table.TypeRef: - return AddTypeRef((TypeRef)tp); - - case Table.TypeDef: - return GetRid((TypeDef)tp); - - case Table.Field: - return GetRid((FieldDef)tp); - - case Table.Method: - return GetRid((MethodDef)tp); - - case Table.Param: - return GetRid((ParamDef)tp); - - case Table.MemberRef: - return AddMemberRef((MemberRef)tp); - - case Table.StandAloneSig: - return AddStandAloneSig((StandAloneSig)tp); - - case Table.Event: - return GetRid((EventDef)tp); - - case Table.Property: - return GetRid((PropertyDef)tp); - - case Table.ModuleRef: - return AddModuleRef((ModuleRef)tp); - - case Table.TypeSpec: - return AddTypeSpec((TypeSpec)tp); - - case Table.Assembly: - return AddAssembly((AssemblyDef)tp, null); - - case Table.AssemblyRef: - return AddAssemblyRef((AssemblyRef)tp); - - case Table.File: - return AddFile((FileDef)tp); - - case Table.ExportedType: - return AddExportedType((ExportedType)tp); - - case Table.MethodSpec: - return AddMethodSpec((MethodSpec)tp); - - case Table.FieldPtr: - case Table.MethodPtr: - case Table.ParamPtr: - case Table.InterfaceImpl: - case Table.Constant: - case Table.CustomAttribute: - case Table.FieldMarshal: - case Table.DeclSecurity: - case Table.ClassLayout: - case Table.FieldLayout: - case Table.EventMap: - case Table.EventPtr: - case Table.PropertyMap: - case Table.PropertyPtr: - case Table.MethodSemantics: - case Table.MethodImpl: - case Table.ImplMap: - case Table.FieldRVA: - case Table.ENCLog: - case Table.ENCMap: - case Table.AssemblyProcessor: - case Table.AssemblyOS: - case Table.AssemblyRefProcessor: - case Table.AssemblyRefOS: - case Table.ManifestResource: - 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; - } - } - - if (tp is null) - Error("IMDTokenProvider is null"); - else - Error("Invalid IMDTokenProvider"); - return 0; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddTypeDefOrRef(ITypeDefOrRef tdr) { - if (tdr is null) { - Error("TypeDefOrRef is null"); - return 0; - } - - var token = new MDToken(tdr.MDToken.Table, AddMDTokenProvider(tdr)); - if (!CodedToken.TypeDefOrRef.Encode(token, out uint encodedToken)) { - Error("Can't encode TypeDefOrRef token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddResolutionScope(IResolutionScope rs) { - if (rs is null) { - return 0; - } - - var token = new MDToken(rs.MDToken.Table, AddMDTokenProvider(rs)); - if (!CodedToken.ResolutionScope.Encode(token, out uint encodedToken)) { - Error("Can't encode ResolutionScope token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddMethodDefOrRef(IMethodDefOrRef mdr) { - if (mdr is null) { - Error("MethodDefOrRef is null"); - return 0; - } - - var token = new MDToken(mdr.MDToken.Table, AddMDTokenProvider(mdr)); - if (!CodedToken.MethodDefOrRef.Encode(token, out uint encodedToken)) { - Error("Can't encode MethodDefOrRef token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddMemberRefParent(IMemberRefParent parent) { - if (parent is null) { - Error("MemberRefParent is null"); - return 0; - } - - var token = new MDToken(parent.MDToken.Table, AddMDTokenProvider(parent)); - if (!CodedToken.MemberRefParent.Encode(token, out uint encodedToken)) { - Error("Can't encode MemberRefParent token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddImplementation(IImplementation impl) { - if (impl is null) { - Error("Implementation is null"); - return 0; - } - - var token = new MDToken(impl.MDToken.Table, AddMDTokenProvider(impl)); - if (!CodedToken.Implementation.Encode(token, out uint encodedToken)) { - Error("Can't encode Implementation token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a - /// - /// Value - /// Its encoded token - protected uint AddCustomAttributeType(ICustomAttributeType cat) { - if (cat is null) { - Error("CustomAttributeType is null"); - return 0; - } - - var token = new MDToken(cat.MDToken.Table, AddMDTokenProvider(cat)); - if (!CodedToken.CustomAttributeType.Encode(token, out uint encodedToken)) { - Error("Can't encode CustomAttributeType token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - return encodedToken; - } - - /// - /// Adds a NestedType row - /// - /// Nested type - /// Declaring type - protected void AddNestedType(TypeDef nestedType, TypeDef declaringType) { - if (nestedType is null || declaringType is null) - return; - uint nestedRid = GetRid(nestedType); - uint dtRid = GetRid(declaringType); - if (nestedRid == 0 || dtRid == 0) - return; - var row = new RawNestedClassRow(nestedRid, dtRid); - nestedClassInfos.Add(declaringType, row); - } - - /// - /// Adds a Module row - /// - /// Module - /// Its new rid - protected uint AddModule(ModuleDef module) { - if (module is null) { - Error("Module is null"); - return 0; - } - if (this.module != 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, - stringsHeap.Add(module.Name), - guidHeap.Add(module.Mvid), - guidHeap.Add(module.EncId), - guidHeap.Add(module.EncBaseId)); - rid = tablesHeap.ModuleTable.Add(row); - moduleDefInfos.Add(module, rid); - AddCustomAttributes(Table.Module, rid, module); - AddCustomDebugInformationList(Table.Module, rid, module); - return rid; - } - - /// - /// Adds a ModuleRef row - /// - /// Module ref - /// Its new rid - protected uint AddModuleRef(ModuleRef modRef) { - if (modRef is null) { - Error("ModuleRef is null"); - return 0; - } - if (moduleRefInfos.TryGetRid(modRef, out uint rid)) - return rid; - var row = new RawModuleRefRow(stringsHeap.Add(modRef.Name)); - rid = tablesHeap.ModuleRefTable.Add(row); - moduleRefInfos.Add(modRef, rid); - AddCustomAttributes(Table.ModuleRef, rid, modRef); - AddCustomDebugInformationList(Table.ModuleRef, rid, modRef); - return rid; - } - - /// - /// Adds an AssemblyRef row - /// - /// Assembly ref - /// Its new rid - protected uint AddAssemblyRef(AssemblyRef asmRef) { - if (asmRef is null) { - Error("AssemblyRef is null"); - return 0; - } - if (assemblyRefInfos.TryGetRid(asmRef, out uint rid)) - return rid; - var version = Utils.CreateVersionWithNoUndefinedValues(asmRef.Version); - var row = new RawAssemblyRefRow((ushort)version.Major, - (ushort)version.Minor, - (ushort)version.Build, - (ushort)version.Revision, - (uint)asmRef.Attributes, - blobHeap.Add(PublicKeyBase.GetRawData(asmRef.PublicKeyOrToken)), - stringsHeap.Add(asmRef.Name), - stringsHeap.Add(asmRef.Culture), - blobHeap.Add(asmRef.Hash)); - rid = tablesHeap.AssemblyRefTable.Add(row); - assemblyRefInfos.Add(asmRef, rid); - AddCustomAttributes(Table.AssemblyRef, rid, asmRef); - AddCustomDebugInformationList(Table.AssemblyRef, rid, asmRef); - return rid; - } - - /// - /// Adds an Assembly row - /// - /// Assembly - /// The public key that should be used - /// Its new rid - protected uint AddAssembly(AssemblyDef asm, byte[] publicKey) { - if (asm is null) { - Error("Assembly is null"); - return 0; - } - if (assemblyInfos.TryGetRid(asm, out uint rid)) - return rid; - - var asmAttrs = asm.Attributes; - if (publicKey is not null) - asmAttrs |= AssemblyAttributes.PublicKey; - else - publicKey = PublicKeyBase.GetRawData(asm.PublicKeyOrToken); - - var version = Utils.CreateVersionWithNoUndefinedValues(asm.Version); - var row = new RawAssemblyRow((uint)asm.HashAlgorithm, - (ushort)version.Major, - (ushort)version.Minor, - (ushort)version.Build, - (ushort)version.Revision, - (uint)asmAttrs, - blobHeap.Add(publicKey), - stringsHeap.Add(asm.Name), - stringsHeap.Add(asm.Culture)); - rid = tablesHeap.AssemblyTable.Add(row); - assemblyInfos.Add(asm, rid); - AddDeclSecurities(new MDToken(Table.Assembly, rid), asm.DeclSecurities); - AddCustomAttributes(Table.Assembly, rid, asm); - AddCustomDebugInformationList(Table.Assembly, rid, asm); - return rid; - } - - /// - /// Adds generic parameters - /// - /// New token of owner - /// All generic params - protected void AddGenericParams(MDToken token, IList gps) { - if (gps is null) - return; - int count = gps.Count; - for (int i = 0; i < count; i++) - AddGenericParam(token, gps[i]); - } - - /// - /// Adds a generic param - /// - /// New token of owner - /// Generic paramater - protected void AddGenericParam(MDToken owner, GenericParam gp) { - if (gp is null) { - Error("GenericParam is null"); - return; - } - if (!CodedToken.TypeOrMethodDef.Encode(owner, out uint encodedOwner)) { - Error("Can't encode TypeOrMethodDef token 0x{0:X8}.", owner.Raw); - encodedOwner = 0; - } - var row = new RawGenericParamRow(gp.Number, - (ushort)gp.Flags, - encodedOwner, - stringsHeap.Add(gp.Name), - gp.Kind is null ? 0 : AddTypeDefOrRef(gp.Kind)); - genericParamInfos.Add(gp, row); - } - - void AddGenericParamConstraints(IList gps) { - if (gps is null) - return; - int count = gps.Count; - for (int i = 0; i < count; i++) { - var gp = gps[i]; - if (gp is null) - continue; - uint rid = genericParamInfos.Rid(gp); - AddGenericParamConstraints(rid, gp.GenericParamConstraints); - } - } - - /// - /// Adds generic parameter constraints - /// - /// New rid of owner generic param - /// Its constraints - protected void AddGenericParamConstraints(uint gpRid, IList constraints) { - if (constraints is null) - return; - int count = constraints.Count; - for (int i = 0; i < count; i++) - AddGenericParamConstraint(gpRid, constraints[i]); - } - - /// - /// Adds a generic parameter constraint - /// - /// New rid of owner generic param - /// Generic parameter constraint - protected void AddGenericParamConstraint(uint gpRid, GenericParamConstraint gpc) { - if (gpc is null) { - Error("GenericParamConstraint is null"); - return; - } - var row = new RawGenericParamConstraintRow(gpRid, AddTypeDefOrRef(gpc.Constraint)); - genericParamConstraintInfos.Add(gpc, row); - } - - /// - /// Adds a InterfaceImpl row - /// - /// New rid of owner - /// All interfaces - protected void AddInterfaceImpls(uint typeDefRid, IList ifaces) { - int count = ifaces.Count; - for (int i = 0; i < count; i++) { - var iface = ifaces[i]; - if (iface is null) - continue; - var row = new RawInterfaceImplRow(typeDefRid, - AddTypeDefOrRef(iface.Interface)); - interfaceImplInfos.Add(iface, row); - } - } - - /// - /// Adds a FieldLayout row - /// - /// Owner field - protected void AddFieldLayout(FieldDef field) { - if (field is null || field.FieldOffset is null) - return; - var rid = GetRid(field); - var row = new RawFieldLayoutRow(field.FieldOffset.Value, rid); - fieldLayoutInfos.Add(field, row); - } - - /// - /// Adds a FieldMarshal row - /// - /// New owner token - /// Owner - protected void AddFieldMarshal(MDToken parent, IHasFieldMarshal hfm) { - if (hfm is null || hfm.MarshalType is null) - return; - var fieldMarshal = hfm.MarshalType; - if (!CodedToken.HasFieldMarshal.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasFieldMarshal token 0x{0:X8}.", parent.Raw); - encodedParent = 0; - } - var row = new RawFieldMarshalRow(encodedParent, - blobHeap.Add(MarshalBlobWriter.Write(module, fieldMarshal, this, OptimizeCustomAttributeSerializedTypeNames))); - fieldMarshalInfos.Add(hfm, row); - } - - /// - /// Adds a FieldRVA row - /// - /// 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); - fieldRVAInfos.Add(field, row); - } - else { - if (field is null || field.InitialValue is null) - return; - var ivBytes = field.InitialValue; - 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); - - uint alignment = ModuleWriterBase.DEFAULT_CONSTANTS_ALIGNMENT; - 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; - var row = new RawFieldRVARow(0, rid); - fieldRVAInfos.Add(field, row); - } - } - - static bool VerifyFieldSize(FieldDef field, int size) { - if (field is null) - return false; - var sig = field.FieldSig; - if (sig is null) - return false; - return field.GetFieldSize() == size; - } - - /// - /// Adds a ImplMap row - /// - /// New owner token - /// Owner - protected void AddImplMap(MDToken parent, IMemberForwarded mf) { - if (mf is null || mf.ImplMap is null) - return; - var implMap = mf.ImplMap; - if (!CodedToken.MemberForwarded.Encode(parent, out uint encodedParent)) { - Error("Can't encode MemberForwarded token 0x{0:X8}.", parent.Raw); - encodedParent = 0; - } - var row = new RawImplMapRow((ushort)implMap.Attributes, - encodedParent, - stringsHeap.Add(implMap.Name), - AddModuleRef(implMap.Module)); - implMapInfos.Add(mf, row); - } - - /// - /// Adds a Constant row - /// - /// New owner token - /// Owner - protected void AddConstant(MDToken parent, IHasConstant hc) { - if (hc is null || hc.Constant is null) - return; - var constant = hc.Constant; - if (!CodedToken.HasConstant.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasConstant token 0x{0:X8}.", parent.Raw); - encodedParent = 0; - } - var row = new RawConstantRow((byte)constant.Type, 0, - encodedParent, - blobHeap.Add(GetConstantValueAsByteArray(constant.Type, constant.Value))); - hasConstantInfos.Add(hc, row); - } - - static readonly byte[] constantClassByteArray = new byte[4]; - static readonly byte[] constantDefaultByteArray = new byte[8]; - byte[] GetConstantValueAsByteArray(ElementType etype, object o) { - if (o is null) { - if (etype == ElementType.Class) - return constantClassByteArray; - Error("Constant is null"); - return constantDefaultByteArray; - } - - var typeCode = Type.GetTypeCode(o.GetType()); - switch (typeCode) { - case TypeCode.Boolean: - VerifyConstantType(etype, ElementType.Boolean); - return BitConverter.GetBytes((bool)o); - - case TypeCode.Char: - VerifyConstantType(etype, ElementType.Char); - return BitConverter.GetBytes((char)o); - - case TypeCode.SByte: - VerifyConstantType(etype, ElementType.I1); - return new byte[1] { (byte)(sbyte)o }; - - case TypeCode.Byte: - VerifyConstantType(etype, ElementType.U1); - return new byte[1] { (byte)o }; - - case TypeCode.Int16: - VerifyConstantType(etype, ElementType.I2); - return BitConverter.GetBytes((short)o); - - case TypeCode.UInt16: - VerifyConstantType(etype, ElementType.U2); - return BitConverter.GetBytes((ushort)o); - - case TypeCode.Int32: - VerifyConstantType(etype, ElementType.I4); - return BitConverter.GetBytes((int)o); - - case TypeCode.UInt32: - VerifyConstantType(etype, ElementType.U4); - return BitConverter.GetBytes((uint)o); - - case TypeCode.Int64: - VerifyConstantType(etype, ElementType.I8); - return BitConverter.GetBytes((long)o); - - case TypeCode.UInt64: - VerifyConstantType(etype, ElementType.U8); - return BitConverter.GetBytes((ulong)o); - - case TypeCode.Single: - VerifyConstantType(etype, ElementType.R4); - return BitConverter.GetBytes((float)o); - - case TypeCode.Double: - VerifyConstantType(etype, ElementType.R8); - return BitConverter.GetBytes((double)o); - - case TypeCode.String: - VerifyConstantType(etype, ElementType.String); - return Encoding.Unicode.GetBytes((string)o); - - default: - Error("Invalid constant type: {0}", typeCode); - return constantDefaultByteArray; - } - } - - void VerifyConstantType(ElementType realType, ElementType expectedType) { - if (realType != expectedType) - Error("Constant value's type is the wrong type: {0} != {1}", realType, expectedType); - } - - /// - /// Adds a DeclSecurity row - /// - /// New owner token - /// All DeclSecurity rows - protected void AddDeclSecurities(MDToken parent, IList declSecurities) { - if (declSecurities is null) - return; - if (!CodedToken.HasDeclSecurity.Encode(parent, out uint encodedParent)) { - Error("Can't encode HasDeclSecurity token 0x{0:X8}.", parent.Raw); - encodedParent = 0; - } - var bwctx = AllocBinaryWriterContext(); - int count = declSecurities.Count; - for (int i = 0; i < count; i++) { - var decl = declSecurities[i]; - if (decl is null) - continue; - var row = new RawDeclSecurityRow((short)decl.Action, - encodedParent, - blobHeap.Add(DeclSecurityWriter.Write(module, decl.SecurityAttributes, this, OptimizeCustomAttributeSerializedTypeNames, bwctx))); - declSecurityInfos.Add(decl, row); - } - Free(ref bwctx); - } - - /// - /// Adds MethodSemantics rows - /// - /// Event - protected void AddMethodSemantics(EventDef evt) { - if (evt is null) { - Error("Event is null"); - return; - } - uint rid = GetRid(evt); - if (rid == 0) - return; - var token = new MDToken(Table.Event, rid); - AddMethodSemantics(token, evt.AddMethod, MethodSemanticsAttributes.AddOn); - AddMethodSemantics(token, evt.RemoveMethod, MethodSemanticsAttributes.RemoveOn); - AddMethodSemantics(token, evt.InvokeMethod, MethodSemanticsAttributes.Fire); - AddMethodSemantics(token, evt.OtherMethods, MethodSemanticsAttributes.Other); - } - - /// - /// Adds MethodSemantics rows - /// - /// Property - protected void AddMethodSemantics(PropertyDef prop) { - if (prop is null) { - Error("Property is null"); - return; - } - uint rid = GetRid(prop); - if (rid == 0) - return; - var token = new MDToken(Table.Property, rid); - AddMethodSemantics(token, prop.GetMethods, MethodSemanticsAttributes.Getter); - AddMethodSemantics(token, prop.SetMethods, MethodSemanticsAttributes.Setter); - AddMethodSemantics(token, prop.OtherMethods, MethodSemanticsAttributes.Other); - } - - void AddMethodSemantics(MDToken owner, IList methods, MethodSemanticsAttributes attrs) { - if (methods is null) - return; - int count = methods.Count; - for (int i = 0; i < count; i++) - AddMethodSemantics(owner, methods[i], attrs); - } - - void AddMethodSemantics(MDToken owner, MethodDef method, MethodSemanticsAttributes flags) { - if (method is null) - return; - uint methodRid = GetRid(method); - if (methodRid == 0) - return; - if (!CodedToken.HasSemantic.Encode(owner, out uint encodedOwner)) { - Error("Can't encode HasSemantic token 0x{0:X8}.", owner.Raw); - encodedOwner = 0; - } - var row = new RawMethodSemanticsRow((ushort)flags, methodRid, encodedOwner); - methodSemanticsInfos.Add(method, row); - } - - void AddMethodImpls(MethodDef method, IList overrides) { - if (overrides is null) - return; - if (method.DeclaringType is null) { - Error("Method declaring type is null"); - return; - } - if (overrides.Count != 0) { - uint rid = GetRid(method.DeclaringType); - 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)); - methodImplInfos.Add(method, row); - } - } - } - - /// - /// Adds a ClassLayout row - /// - /// Type - protected void AddClassLayout(TypeDef type) { - if (type is null || type.ClassLayout is null) - return; - var rid = GetRid(type); - var classLayout = type.ClassLayout; - var row = new RawClassLayoutRow(classLayout.PackingSize, classLayout.ClassSize, rid); - classLayoutInfos.Add(type, row); - } - - void AddResources(IList resources) { - if (NoDotNetResources) - return; - if (resources is null) - return; - int count = resources.Count; - for (int i = 0; i < count; i++) - AddResource(resources[i]); - } - - void AddResource(Resource resource) { - Debug.Assert(!NoDotNetResources); - if (resource is EmbeddedResource er) { - AddEmbeddedResource(er); - return; - } - - if (resource is AssemblyLinkedResource alr) { - AddAssemblyLinkedResource(alr); - return; - } - - if (resource is LinkedResource lr) { - AddLinkedResource(lr); - return; - } - - if (resource is null) - Error("Resource is null"); - else - Error("Invalid resource type: '{0}'.", resource.GetType()); - } - - uint AddEmbeddedResource(EmbeddedResource er) { - Debug.Assert(!isStandaloneDebugMetadata); - Debug.Assert(!NoDotNetResources); - if (er is null) { - Error("EmbeddedResource is null"); - return 0; - } - if (manifestResourceInfos.TryGetRid(er, out uint rid)) - return rid; - var row = new RawManifestResourceRow(netResources.NextOffset, - (uint)er.Attributes, - stringsHeap.Add(er.Name), - 0); - rid = tablesHeap.ManifestResourceTable.Add(row); - manifestResourceInfos.Add(er, rid); - embeddedResourceToByteArray[er] = netResources.Add(er.CreateReader()); - AddCustomAttributes(Table.ManifestResource, rid, er); - AddCustomDebugInformationList(Table.ManifestResource, rid, er); - return rid; - } - - uint AddAssemblyLinkedResource(AssemblyLinkedResource alr) { - Debug.Assert(!NoDotNetResources); - if (alr is null) { - Error("AssemblyLinkedResource is null"); - return 0; - } - if (manifestResourceInfos.TryGetRid(alr, out uint rid)) - return rid; - var row = new RawManifestResourceRow(0, - (uint)alr.Attributes, - stringsHeap.Add(alr.Name), - AddImplementation(alr.Assembly)); - rid = tablesHeap.ManifestResourceTable.Add(row); - manifestResourceInfos.Add(alr, rid); - AddCustomAttributes(Table.ManifestResource, rid, alr); - AddCustomDebugInformationList(Table.ManifestResource, rid, alr); - return rid; - } - - uint AddLinkedResource(LinkedResource lr) { - Debug.Assert(!NoDotNetResources); - if (lr is null) { - Error("LinkedResource is null"); - return 0; - } - if (manifestResourceInfos.TryGetRid(lr, out uint rid)) - return rid; - var row = new RawManifestResourceRow(0, - (uint)lr.Attributes, - stringsHeap.Add(lr.Name), - AddImplementation(lr.File)); - rid = tablesHeap.ManifestResourceTable.Add(row); - manifestResourceInfos.Add(lr, rid); - AddCustomAttributes(Table.ManifestResource, rid, lr); - AddCustomDebugInformationList(Table.ManifestResource, rid, lr); - return rid; - } - - /// - /// Adds a File row - /// - /// File - /// Its new rid - protected uint AddFile(FileDef file) { - if (file is null) { - Error("FileDef is null"); - return 0; - } - if (fileDefInfos.TryGetRid(file, out uint rid)) - return rid; - var row = new RawFileRow((uint)file.Flags, - stringsHeap.Add(file.Name), - blobHeap.Add(file.HashValue)); //TODO: Re-calculate the hash value if possible - rid = tablesHeap.FileTable.Add(row); - fileDefInfos.Add(file, rid); - AddCustomAttributes(Table.File, rid, file); - AddCustomDebugInformationList(Table.File, rid, file); - return rid; - } - - /// - /// Adds a ExportedType row - /// - /// Exported type - /// Its new rid - protected uint AddExportedType(ExportedType et) { - if (et is null) { - Error("ExportedType is null"); - return 0; - } - if (exportedTypeInfos.TryGetRid(et, out uint rid)) - return rid; - exportedTypeInfos.Add(et, 0); // Prevent inf recursion - var row = new RawExportedTypeRow((uint)et.Attributes, - et.TypeDefId, //TODO: Should be updated with the new rid - stringsHeap.Add(et.TypeName), - stringsHeap.Add(et.TypeNamespace), - AddImplementation(et.Implementation)); - rid = tablesHeap.ExportedTypeTable.Add(row); - exportedTypeInfos.SetRid(et, rid); - AddCustomAttributes(Table.ExportedType, rid, et); - AddCustomDebugInformationList(Table.ExportedType, rid, et); - return rid; - } - - /// - /// Gets a #Blob offset of a type signature - /// - /// Type sig - /// Extra data to append the signature if - /// is true. - /// #Blob offset - protected uint GetSignature(TypeSig ts, byte[] extraData) { - byte[] blob; - if (ts is null) { - Error("TypeSig is null"); - blob = null; - } - else { - var bwctx = AllocBinaryWriterContext(); - blob = SignatureWriter.Write(this, ts, bwctx); - Free(ref bwctx); - } - AppendExtraData(ref blob, extraData); - return blobHeap.Add(blob); - } - - /// - /// Gets a #Blob offset of a calling convention signature - /// - /// Signature - /// #Blob offset - protected uint GetSignature(CallingConventionSig sig) { - if (sig is null) { - Error("CallingConventionSig is null"); - return 0; - } - - var bwctx = AllocBinaryWriterContext(); - var blob = SignatureWriter.Write(this, sig, bwctx); - Free(ref bwctx); - AppendExtraData(ref blob, sig.ExtraData); - return blobHeap.Add(blob); - } - - void AppendExtraData(ref byte[] blob, byte[] extraData) { - 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); - } - } - - /// - /// Adds a CustomAttribute row - /// - /// Owner table - /// New owner rid - /// Onwer - 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); - int count = caList.Count; - for (int i = 0; i < count; i++) - AddCustomAttribute(token, caList[i]); - } - - void AddCustomAttribute(MDToken token, CustomAttribute ca) { - if (ca is null) { - Error("Custom attribute is null"); - return; - } - if (!CodedToken.HasCustomAttribute.Encode(token, out uint encodedToken)) { - Error("Can't encode HasCustomAttribute token 0x{0:X8}.", token.Raw); - encodedToken = 0; - } - 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) { - Debug.Assert(debugMetadata is not null); - if (debugMetadata is 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 is not null); - var body = method.Body; - if (body is null) - return; - - GetSingleDocument(body, out var singleDoc, out var firstDoc, out bool 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 is 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 is null) - continue; - if (seqPoint.Document is 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 = 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 is not null); - if (!debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint 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 is null) - continue; - var doc = seqPt.Document; - if (doc is null) - continue; - if (firstDoc is 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 is 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 is 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 is not null); - Debug.Assert(cdis.Count != 0); - - var token = new MDToken(table, rid); - if (!CodedToken.HasCustomDebugInformation.Encode(token, out uint encodedToken)) { - Error("Couldn't encode HasCustomDebugInformation token 0x{0:X8}.", token.Raw); - return; - } - - for (int i = 0; i < cdis.Count; i++) { - var cdi = cdis[i]; - if (cdi is 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 is not null); - - switch (cdi.Kind) { - case PdbCustomDebugInfoKind.UsingGroups: - case PdbCustomDebugInfoKind.ForwardMethodInfo: - case PdbCustomDebugInfoKind.ForwardModuleInfo: - 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; - - 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: - case PdbCustomDebugInfoKind.CompilationMetadataReferences: - case PdbCustomDebugInfoKind.CompilationOptions: - case PdbCustomDebugInfoKind.TypeDefinitionDocuments: - case PdbCustomDebugInfoKind.EditAndContinueStateMachineStateMap: - case PdbCustomDebugInfoKind.PrimaryConstructorInformationBlob: - 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); - break; - } - } - - void AddStateMachineMethod(PdbCustomDebugInfo cdi, uint moveNextMethodToken, MethodDef kickoffMethod) { - Debug.Assert(new MDToken(moveNextMethodToken).Table == Table.Method); - Debug.Assert(debugMetadata is not null); - if (kickoffMethod is null) { - Error("KickoffMethod is null"); - return; - } - 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 is not 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 is null) - return; - int numMethods = NumberOfMethods; - for (int i = 0; i < numMethods; i++) - debugMetadata.tablesHeap.MethodDebugInformationTable.Create(new RawMethodDebugInformationRow()); - } - - void AddPdbDocuments() { - if (debugMetadata is null) - return; - foreach (var doc in module.PdbState.Documents) - AddPdbDocument(doc); - } - - uint AddPdbDocument(PdbDocument doc) { - Debug.Assert(debugMetadata is not null); - if (doc is null) { - Error("PdbDocument is null"); - return 0; - } - if (debugMetadata.pdbDocumentInfos.TryGetRid(doc, out uint 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 is not null); - if (name is 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.WriteByte(0); - else - writer.WriteBytes(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 is not null); - if (scope is null) - return 0; - if (debugMetadata.importScopeInfos.TryGetRid(scope, out uint 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 is not null); - if (local is 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 is not null); - if (constant is 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 - /// 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 is null) - throw new InvalidOperationException(); - var pdbHeap = debugMetadata.PdbHeap; - pdbHeap.EntryPoint = entryPointToken; - - tablesHeap.GetSystemTableRows(out ulong systemTablesMask, pdbHeap.TypeSystemTableRows); - debugMetadata.tablesHeap.SetSystemTableRows(pdbHeap.TypeSystemTableRows); - if (!debugMetadata.methodDebugInformationInfosUsed) - debugMetadata.tablesHeap.MethodDebugInformationTable.Reset(); - pdbHeap.ReferencedTypeSystemTables = systemTablesMask; - var writer = new DataWriter(output); - debugMetadata.OnBeforeSetOffset(); - debugMetadata.SetOffset(0, 0); - debugMetadata.GetFileLength(); - debugMetadata.VerifyWriteTo(writer); - pdbIdOffset = (long)pdbHeap.PdbIdOffset; - } - - /// - uint ISignatureWriterHelper.ToEncodedToken(ITypeDefOrRef typeDefOrRef) => AddTypeDefOrRef(typeDefOrRef); - - /// - 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); - - /// - /// Called before any other methods - /// - protected virtual void Initialize() { - } - - /// - /// Gets all s that should be saved in the meta data - /// - protected abstract TypeDef[] GetAllTypeDefs(); - - /// - /// Initializes TypeDef rids and creates raw rows, but does not initialize - /// any columns. - /// - protected abstract void AllocateTypeDefRids(); - - /// - /// Allocates Field, Method, Property, Event, Param: - /// rid and raw row, but doesn't initialize the raw row. - /// Initializes TypeDef columns: FieldList, MethodList. - /// Initializes Method column: ParamList. - /// Initializes and . - /// - protected abstract void AllocateMemberDefRids(); - - /// - /// Adds a . Its custom attributes are also added. - /// - /// Type reference - /// Its new rid - protected abstract uint AddTypeRef(TypeRef tr); - - /// - /// Adds a . Its custom attributes are also added. - /// - /// Type spec - /// Its new rid - protected abstract uint AddTypeSpec(TypeSpec ts); - - /// - /// Adds a . Its custom attributes are also added. - /// - /// Member ref - /// Its new rid - protected abstract uint AddMemberRef(MemberRef mr); - - /// - /// Adds a . Its custom attributes are also added. - /// - /// Stand alone sig - /// Its new rid - protected abstract uint AddStandAloneSig(StandAloneSig sas); - - /// - /// Adds a . Its custom attributes are also added. - /// - /// Method spec - /// Its new rid - protected abstract uint AddMethodSpec(MethodSpec ms); - - /// - /// Called before sorting the CustomAttribute table. This is the last time anything - /// can be inserted into this table. - /// - protected virtual void BeforeSortingCustomAttributes() { - } - - /// - /// Called after everything has been initialized. The sub class can initialize more - /// rows if necessary or do nothing. After this method has been called, nothing else - /// can be added. - /// - protected virtual void EverythingInitialized() { - } - - const uint HEAP_ALIGNMENT = 4; - - 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) - throw new InvalidOperationException(); - 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 - // 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; - - if (initAll) { - // #Strings heap is initialized in OnBeforeSetOffset() - 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(); - offset += len; - rva += len; - - foreach (var heap in metadataHeader.Heaps) { - offset = offset.AlignUp(HEAP_ALIGNMENT); - rva = rva.AlignUp(HEAP_ALIGNMENT); - heap.SetOffset(offset, rva); - len = heap.GetFileLength(); - 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 && initAll) - UpdateMethodAndFieldRvas(); - } - - internal void UpdateMethodAndFieldRvas() { - UpdateMethodRvas(); - UpdateFieldRvas(); - } - - IList GetHeaps() { - var heaps = new List(); - - 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 { - 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); - - heaps.AddRange(options.CustomHeaps); - options.RaiseMetadataHeapsAdded(new MetadataHeapsAddedEventArgs(this, heaps)); - } - - return heaps; - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - var rva2 = rva; - metadataHeader.VerifyWriteTo(writer); - rva2 += metadataHeader.GetFileLength(); - - foreach (var heap in metadataHeader.Heaps) { - writer.WriteZeroes((int)(rva2.AlignUp(HEAP_ALIGNMENT) - rva2)); - rva2 = rva2.AlignUp(HEAP_ALIGNMENT); - heap.VerifyWriteTo(writer); - rva2 += heap.GetFileLength(); - } - } - - /// - /// Sorts the s - /// - /// All s - /// A sorted list - protected static List Sort(IEnumerable pds) { - var sorted = new List(pds); - sorted.Sort((a, b) => { - if (a is null) - return -1; - if (b is null) - return 1; - return a.Sequence.CompareTo(b.Sequence); - }); - return sorted; - } - - DataWriterContext AllocBinaryWriterContext() { - if (binaryWriterContexts.Count == 0) - return new DataWriterContext(); - var res = binaryWriterContexts[binaryWriterContexts.Count - 1]; - binaryWriterContexts.RemoveAt(binaryWriterContexts.Count - 1); - return res; - } - - void Free(ref DataWriterContext 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/Plugins/dnlib/DotNet/Writer/MetadataErrorContext.cs b/Plugins/dnlib/DotNet/Writer/MetadataErrorContext.cs deleted file mode 100644 index dee31d7..0000000 --- a/Plugins/dnlib/DotNet/Writer/MetadataErrorContext.cs +++ /dev/null @@ -1,72 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Writer/MetadataEvent.cs b/Plugins/dnlib/DotNet/Writer/MetadataEvent.cs deleted file mode 100644 index 0e90687..0000000 --- a/Plugins/dnlib/DotNet/Writer/MetadataEvent.cs +++ /dev/null @@ -1,84 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// All events - /// - public enum MetadataEvent { - /// - /// Creating the tables has just begun - /// - BeginCreateTables, - - /// - /// Before allocating all TypeDef RIDs - /// - AllocateTypeDefRids, - - /// - /// Before allocating all MemberDef RIDs - /// - AllocateMemberDefRids, - - /// - /// The rids of types, fields, methods, events, properties and parameters are - /// now known. - /// - MemberDefRidsAllocated, - - /// - /// 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 - /// written yet. - /// - MemberDefsInitialized, - - /// - /// Before sorting most tables - /// - BeforeSortTables, - - /// - /// Most of the tables that should be sorted have been sorted. The CustomAttribute - /// table is still unsorted since it hasn't been created yet. - /// - MostTablesSorted, - - /// - /// Custom attributes of all types, fields, methods, events, properties and parameters - /// have now been written. - /// - MemberDefCustomAttributesWritten, - - /// - /// All resources are about to be added to the .NET resources table - /// - BeginAddResources, - - /// - /// All resources have been added to the .NET resources table - /// - EndAddResources, - - /// - /// All method bodies are about to be written - /// - BeginWriteMethodBodies, - - /// - /// All method bodies have been written. Their RVAs are still not known. - /// - EndWriteMethodBodies, - - /// - /// All tables are now sorted, including the CustomAttribute table. - /// - OnAllTablesSorted, - - /// - /// All tables have been created and all rows populated. The only columns that haven't - /// been initialized yet are the ones that are RVAs. - /// - EndCreateTables, - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MetadataHeader.cs b/Plugins/dnlib/DotNet/Writer/MetadataHeader.cs deleted file mode 100644 index 4fe2841..0000000 --- a/Plugins/dnlib/DotNet/Writer/MetadataHeader.cs +++ /dev/null @@ -1,170 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using System.Text; -using dnlib.IO; -using dnlib.PE; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Writer { - /// - /// options - /// - public sealed class MetadataHeaderOptions { - /// - /// Default version string - /// - public const string DEFAULT_VERSION_STRING = MDHeaderRuntimeVersion.MS_CLR_20; - - /// - /// Default header signature - /// - public const uint DEFAULT_SIGNATURE = 0x424A5342; - - /// - /// MD header signature. Default value is - /// - public uint? Signature; - - /// - /// Major version. Default is 1. MS' CLR supports v0.x (x >= 19) and v1.1, nothing else. - /// - public ushort? MajorVersion; - - /// - /// Minor version. Default is 1. - /// - public ushort? MinorVersion; - - /// - /// Reserved and should be 0. - /// - public uint? Reserved1; - - /// - /// Version string. Default is . It's stored as a - /// zero-terminated UTF-8 string. Length should be <= 255 bytes. - /// - public string VersionString; - - /// - /// Storage flags should be 0 - /// - public StorageFlags? StorageFlags; - - /// - /// Reserved and should be 0 - /// - public byte? Reserved2; - - /// - /// Creates portable PDB v1.0 options - /// - /// - public static MetadataHeaderOptions CreatePortablePdbV1_0() => - new MetadataHeaderOptions() { - Signature = DEFAULT_SIGNATURE, - MajorVersion = 1, - MinorVersion = 1, - Reserved1 = 0, - VersionString = MDHeaderRuntimeVersion.PORTABLE_PDB_V1_0, - StorageFlags = 0, - Reserved2 = 0, - }; - } - - /// - /// Meta data header. IMAGE_COR20_HEADER.Metadata points to this header. - /// - public sealed class MetadataHeader : IChunk { - IList heaps; - readonly MetadataHeaderOptions options; - uint length; - FileOffset offset; - RVA rva; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets/sets the heaps - /// - public IList Heaps { - get => heaps; - set => heaps = value; - } - - /// - /// Default constructor - /// - public MetadataHeader() - : this(null) { - } - - /// - /// Constructor - /// - /// Options - public MetadataHeader(MetadataHeaderOptions options) => this.options = options ?? new MetadataHeaderOptions(); - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - - length = 16; - length += (uint)GetVersionString().Length; - length = Utils.AlignUp(length, 4); - length += 4; - 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); - } - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - 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.WriteInt32(Utils.AlignUp(s.Length, 4)); - writer.WriteBytes(s); - writer.WriteZeroes(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); - 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)); - if (s.Length > 32) - throw new ModuleWriterException($"Heap name '{heap.Name}' is > 32 bytes"); - writer.WriteZeroes(Utils.AlignUp(s.Length, 4) - s.Length); - } - } - - byte[] GetVersionString() => Encoding.UTF8.GetBytes((options.VersionString ?? MetadataHeaderOptions.DEFAULT_VERSION_STRING) + "\0"); - byte[] GetAsciizName(string s) => Encoding.ASCII.GetBytes(s + "\0"); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MethodBody.cs b/Plugins/dnlib/DotNet/Writer/MethodBody.cs deleted file mode 100644 index abcfbbc..0000000 --- a/Plugins/dnlib/DotNet/Writer/MethodBody.cs +++ /dev/null @@ -1,163 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; -using dnlib.IO; -using dnlib.PE; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// Method body chunk - /// - public sealed class MethodBody : IChunk { - const uint EXTRA_SECTIONS_ALIGNMENT = 4; - - readonly bool isTiny; - readonly byte[] code; - readonly byte[] extraSections; - uint length; - FileOffset offset; - RVA rva; - readonly uint localVarSigTok; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets the code - /// - public byte[] Code => code; - - /// - /// Gets the extra sections (exception handlers) or null - /// - public byte[] ExtraSections => extraSections; - - /// - /// Gets the token of the locals - /// - public uint LocalVarSigTok => localVarSigTok; - - /// - /// true if it's a fat body - /// - public bool IsFat => !isTiny; - - /// - /// true if it's a tiny body - /// - public bool IsTiny => isTiny; - - /// - /// true if there's an extra section - /// - public bool HasExtraSections => extraSections is not null && extraSections.Length > 0; - - /// - /// Constructor - /// - /// Code - public MethodBody(byte[] code) - : this(code, null, 0) { - } - - /// - /// Constructor - /// - /// Code - /// Extra sections or null - public MethodBody(byte[] code, byte[] extraSections) - : this(code, extraSections, 0) { - } - - /// - /// Constructor - /// - /// Code - /// Extra sections or null - /// Token of locals - public MethodBody(byte[] code, byte[] extraSections, uint localVarSigTok) { - isTiny = (code[0] & 3) == 2; - this.code = code; - this.extraSections = extraSections; - this.localVarSigTok = localVarSigTok; - } - - /// - /// Gets the approximate size of the method body (code + exception handlers) - /// - public int GetApproximateSizeOfMethodBody() { - int len = code.Length; - if (extraSections is not null) { - len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); - len += extraSections.Length; - len = Utils.AlignUp(len, EXTRA_SECTIONS_ALIGNMENT); - } - 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) { - var rva2 = rva + (uint)code.Length; - rva2 = rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT); - rva2 += (uint)extraSections.Length; - length = (uint)rva2 - (uint)rva; - } - else - length = (uint)code.Length; - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - writer.WriteBytes(code); - //EncryptionUtil.WriteWitchEncIfNeed(writer, w => w.WriteBytes(code), e => e.MethodBodyEnc, EncryptionContext.SmallSegmentSize); - if (HasExtraSections) { - var rva2 = rva + (uint)code.Length; - writer.WriteZeroes((int)rva2.AlignUp(EXTRA_SECTIONS_ALIGNMENT) - (int)rva2); - writer.WriteBytes(extraSections); - } - } - - /// - public override int GetHashCode() => Utils.GetHashCode(code) + Utils.GetHashCode(extraSections); - - /// - public override bool Equals(object obj) { - var other = obj as MethodBody; - if (other is null) - return false; - return Utils.Equals(code, other.code) && - Utils.Equals(extraSections, other.extraSections); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MethodBodyChunks.cs b/Plugins/dnlib/DotNet/Writer/MethodBodyChunks.cs deleted file mode 100644 index 63ab29a..0000000 --- a/Plugins/dnlib/DotNet/Writer/MethodBodyChunks.cs +++ /dev/null @@ -1,196 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Stores all method body chunks - /// - public sealed class MethodBodyChunks : IChunk { - const uint FAT_BODY_ALIGNMENT = 4; - Dictionary tinyMethodsDict; - Dictionary fatMethodsDict; - readonly List tinyMethods; - readonly List fatMethods; - readonly List reusedMethods; - readonly Dictionary rvaToReusedMethod; - readonly bool shareBodies; - FileOffset offset; - RVA rva; - uint length; - bool setOffsetCalled; - 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; - - /// - public RVA RVA => rva; - - /// - /// Gets the number of bytes saved by re-using method bodies - /// - 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 - /// - /// true if bodies can be shared - public MethodBodyChunks(bool shareBodies) { - this.shareBodies = shareBodies; - alignFatBodies = true; - if (shareBodies) { - tinyMethodsDict = new Dictionary(); - fatMethodsDict = new Dictionary(); - } - tinyMethods = new List(); - fatMethods = new List(); - reusedMethods = new List(); - rvaToReusedMethod = new Dictionary(); - } - - /// - /// Adds a and returns the one that has been cached - /// - /// The method body - /// The cached method body - 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 (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)) { - savedBytes += (uint)methodBody.GetApproximateSizeOfMethodBody(); - return cached; - } - dict[methodBody] = methodBody; - } - var list = methodBody.IsFat ? fatMethods : tinyMethods; - list.Add(methodBody); - return methodBody; - } - - /// Removes the specified method body from this chunk - /// The method body - /// if the method body is removed - public bool Remove(MethodBody methodBody) { - if (methodBody is 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(Func getNewFileOffset) { - foreach (var info in reusedMethods) { - var offset = getNewFileOffset(info.RVA); - info.MethodBody.SetOffset(offset, info.RVA); - } - } - - 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.Position = destStreamBaseOffset + (uint)info.MethodBody.FileOffset; - info.MethodBody.VerifyWriteTo(writer); - } - } - - /// - public void SetOffset(FileOffset offset, RVA rva) { - setOffsetCalled = true; - this.offset = offset; - this.rva = rva; - - tinyMethodsDict = null; - fatMethodsDict = null; - - var rva2 = rva; - foreach (var mb in tinyMethods) { - mb.SetOffset(offset, rva2); - uint len = mb.GetFileLength(); - rva2 += len; - offset += len; - } - - foreach (var mb in fatMethods) { - if (alignFatBodies) { - uint padding = (uint)rva2.AlignUp(FAT_BODY_ALIGNMENT) - (uint)rva2; - rva2 += padding; - offset += padding; - } - mb.SetOffset(offset, rva2); - uint len = mb.GetFileLength(); - rva2 += len; - offset += len; - } - - length = (uint)rva2 - (uint)rva; - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - var rva2 = rva; - foreach (var mb in tinyMethods) { - mb.VerifyWriteTo(writer); - rva2 += mb.GetFileLength(); - } - - foreach (var mb in fatMethods) { - if (alignFatBodies) { - int padding = (int)rva2.AlignUp(FAT_BODY_ALIGNMENT) - (int)rva2; - writer.WriteZeroes(padding); - rva2 += (uint)padding; - } - mb.VerifyWriteTo(writer); - rva2 += mb.GetFileLength(); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MethodBodyWriter.cs b/Plugins/dnlib/DotNet/Writer/MethodBodyWriter.cs deleted file mode 100644 index 0fad93f..0000000 --- a/Plugins/dnlib/DotNet/Writer/MethodBodyWriter.cs +++ /dev/null @@ -1,345 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.Emit; - -namespace dnlib.DotNet.Writer { - /// - /// Returns tokens of token types, strings and signatures - /// - public interface ITokenProvider : IWriterError { - /// - /// Gets the token of - /// - /// A token type or a string or a signature - /// The token - MDToken GetToken(object o); - - /// - /// Gets a StandAloneSig token - /// - /// All locals - /// The original token or 0 if none - /// A StandAloneSig token or 0 if is - /// empty. - MDToken GetToken(IList locals, uint origToken); - } - - /// - /// Writes CIL method bodies - /// - public sealed class MethodBodyWriter : MethodBodyWriterBase { - readonly ITokenProvider helper; - CilBody cilBody; - bool keepMaxStack; - uint codeSize; - uint maxStack; - byte[] code; - byte[] extraSections; - uint localVarSigTok; - - /// - /// Gets the code as a byte array. This is valid only after calling . - /// The size of this array is not necessarily a multiple of 4, even if there are exception - /// handlers present. See also - /// - 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 => extraSections; - - /// - /// Gets the token of the locals - /// - 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; - cilBody = method.Body; - this.keepMaxStack = keepMaxStack; - } - - /// - /// Constructor - /// - /// Helps this instance - /// The CIL method body - public MethodBodyWriter(ITokenProvider helper, CilBody cilBody) - : this(helper, cilBody, false) { - } - - /// - /// Constructor - /// - /// Helps this instance - /// The CIL method body - /// Keep the original max stack value that has been initialized - /// in - public MethodBodyWriter(ITokenProvider helper, CilBody cilBody, bool keepMaxStack) - : base(cilBody.Instructions, cilBody.ExceptionHandlers) { - this.helper = helper; - this.cilBody = cilBody; - this.keepMaxStack = keepMaxStack; - } - - internal MethodBodyWriter(ITokenProvider 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 - /// - public void Write() { - codeSize = InitializeInstructionOffsets(); - maxStack = keepMaxStack ? cilBody.MaxStack : GetMaxStack(); - if (NeedFatHeader()) - WriteFatHeader(); - else - WriteTinyHeader(); - if (exceptionHandlers.Count > 0) - WriteExceptionHandlers(); - } - - /// - /// Gets the code and (possible) exception handlers in one array. The exception handlers - /// are 4-byte aligned. - /// - /// 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 is null ? 0 : padding + extraSections.Length)]; - Array.Copy(code, 0, bytes, 0, code.Length); - if (extraSections is not null) - Array.Copy(extraSections, 0, bytes, code.Length + padding, extraSections.Length); - return bytes; - } - - bool NeedFatHeader() { - //TODO: If locals has cust attrs or custom debug infos, we also need a fat header - return codeSize > 0x3F || - exceptionHandlers.Count > 0 || - cilBody.HasVariables || - maxStack > 8; - } - - void WriteFatHeader() { - if (maxStack > ushort.MaxValue) { - Error("MaxStack is too big"); - maxStack = ushort.MaxValue; - } - - ushort flags = 0x3003; - if (exceptionHandlers.Count > 0) - flags |= 8; - if (cilBody.InitLocals) - flags |= 0x10; - - code = new byte[12 + codeSize]; - var writer = new ArrayWriter(code); - 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"); - } - - IList GetLocals() { - var localsSig = new TypeSig[cilBody.Variables.Count]; - for (int i = 0; i < cilBody.Variables.Count; i++) - localsSig[i] = cilBody.Variables[i].Type; - return localsSig; - } - - void WriteTinyHeader() { - localVarSigTok = 0; - code = new byte[1 + codeSize]; - var writer = new ArrayWriter(code); - writer.WriteByte((byte)((codeSize << 2) | 2)); - if (WriteInstructions(ref writer) != codeSize) - Error("Didn't write all code bytes"); - } - - void WriteExceptionHandlers() { - if (NeedFatExceptionClauses()) - extraSections = WriteFatExceptionClauses(); - else - 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; - - 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)) - return true; - } - - return false; - } - - bool FitsInSmallExceptionClause(Instruction start, Instruction end) { - uint offs1 = GetOffset2(start); - uint offs2 = GetOffset2(end); - if (offs2 < offs1) - return false; - return offs1 <= ushort.MaxValue && offs2 - offs1 <= byte.MaxValue; - } - - uint GetOffset2(Instruction instr) { - if (instr is null) - return codeSize; - return GetOffset(instr); - } - - 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 ArrayWriter(data); - writer.WriteUInt32((((uint)numExceptionHandlers * 24 + 4) << 8) | 0x41); - for (int i = 0; i < numExceptionHandlers; i++) { - var eh = exceptionHandlers[i]; - uint offs1, offs2; - - writer.WriteUInt32((uint)eh.HandlerType); - - offs1 = GetOffset2(eh.TryStart); - offs2 = GetOffset2(eh.TryEnd); - if (offs2 <= offs1) - Error("Exception handler: TryEnd <= TryStart"); - writer.WriteUInt32(offs1); - writer.WriteUInt32(offs2 - offs1); - - offs1 = GetOffset2(eh.HandlerStart); - offs2 = GetOffset2(eh.HandlerEnd); - if (offs2 <= offs1) - Error("Exception handler: HandlerEnd <= HandlerStart"); - writer.WriteUInt32(offs1); - writer.WriteUInt32(offs2 - offs1); - - if (eh.IsCatch) - writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); - else if (eh.IsFilter) - writer.WriteUInt32(GetOffset2(eh.FilterStart)); - else - writer.WriteInt32(0); - } - - if (writer.Position != data.Length) - throw new InvalidOperationException(); - return data; - } - - 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 ArrayWriter(data); - writer.WriteUInt32((((uint)numExceptionHandlers * 12 + 4) << 8) | 1); - for (int i = 0; i < numExceptionHandlers; i++) { - var eh = exceptionHandlers[i]; - uint offs1, offs2; - - writer.WriteUInt16((ushort)eh.HandlerType); - - offs1 = GetOffset2(eh.TryStart); - offs2 = GetOffset2(eh.TryEnd); - if (offs2 <= offs1) - Error("Exception handler: TryEnd <= TryStart"); - 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.WriteUInt16((ushort)offs1); - writer.WriteByte((byte)(offs2 - offs1)); - - if (eh.IsCatch) - writer.WriteUInt32(helper.GetToken(eh.CatchType).Raw); - else if (eh.IsFilter) - writer.WriteUInt32(GetOffset2(eh.FilterStart)); - else - writer.WriteInt32(0); - } - - if (writer.Position != data.Length) - throw new InvalidOperationException(); - return data; - } - - /// - 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); - - /// - 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.WriteUInt32(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.WriteUInt32(helper.GetToken(instr.Operand).Raw); - - /// - protected override void WriteInlineType(ref ArrayWriter writer, Instruction instr) => writer.WriteUInt32(helper.GetToken(instr.Operand).Raw); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/MethodBodyWriterBase.cs b/Plugins/dnlib/DotNet/Writer/MethodBodyWriterBase.cs deleted file mode 100644 index 1e92883..0000000 --- a/Plugins/dnlib/DotNet/Writer/MethodBodyWriterBase.cs +++ /dev/null @@ -1,438 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; -using dnlib.DotNet.Emit; -using dnlib.Protection; - -namespace dnlib.DotNet.Writer { - /// - /// Base class of all CIL method body writers - /// - public abstract class MethodBodyWriterBase { - /// - protected IList instructions; - /// - protected IList exceptionHandlers; - readonly Dictionary offsets = new Dictionary(); - uint firstInstructionOffset; - int errors; - MaxStackCalculator maxStackCalculator = MaxStackCalculator.Create(); - - /// - /// true if there was at least one error - /// - public bool ErrorDetected => errors > 0; - - internal MethodBodyWriterBase() { - } - - /// - /// Constructor - /// - /// All instructions - /// All exception handlers - protected MethodBodyWriterBase(IList instructions, IList exceptionHandlers) { - this.instructions = instructions; - this.exceptionHandlers = exceptionHandlers; - } - - internal void Reset(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. - /// - /// Error message - protected void Error(string message) { - errors++; - ErrorImpl(message); - } - - /// - /// Called when an error is detected (eg. a null pointer). The error can be - /// ignored but the method won't be valid. - /// - /// Error message - protected virtual void ErrorImpl(string message) { - } - - /// - /// Gets max stack value - /// - protected uint GetMaxStack() { - if (instructions.Count == 0) - return 0; - maxStackCalculator.Reset(instructions, exceptionHandlers); - 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; - } - return maxStack; - } - - /// - /// Gets the offset of an instruction - /// - /// The instruction - /// The offset or 0 if is null or not - /// present in the list of all instructions. - protected uint GetOffset(Instruction instr) { - if (instr is null) { - Error("Instruction is null"); - return 0; - } - 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; - } - - /// - /// Initializes instruction offsets and returns the total code size - /// - /// Size of code - protected uint InitializeInstructionOffsets() { - uint offset = 0; - var instructions = this.instructions; - for (int i = 0; i < instructions.Count; i++) { - var instr = instructions[i]; - if (instr is null) - continue; - offsets[instr] = offset; - offset += GetSizeOfInstruction(instr); - } - return offset; - } - - /// - /// Gets the size of an instruction - /// - /// The instruction - /// Size of the instruction in bytes - protected virtual uint GetSizeOfInstruction(Instruction instr) => (uint)instr.GetSize(); - - /// - /// Writes all instructions to at its current offset - /// - /// The instruction writer - /// Number of bytes written - protected uint WriteInstructions(ref ArrayWriter writer) { - firstInstructionOffset = (uint)writer.Position; - var instructions = this.instructions; - for (int i = 0; i < instructions.Count; i++) { - var instr = instructions[i]; - if (instr is null) - continue; - WriteInstruction(ref writer, instr); - } - - IEncryption encryption = EncryptionContext.Encryption; - if (encryption != null && encryption.MethodBodyEnc != null) { - encryption.MethodBodyEnc.EncryptBySegment(writer.DataUnsafe, firstInstructionOffset, (uint)writer.Position - firstInstructionOffset, encryption.EncParam, EncryptionContext.SmallSegmentSize); - } - - return ToInstructionOffset(ref writer); - } - - - /// - /// Gets the current offset in the instruction stream. This offset is relative to - /// the first written instruction. - /// - /// The instruction writer - /// Current offset, relative to the first written instruction - protected uint ToInstructionOffset(ref ArrayWriter writer) => (uint)writer.Position - firstInstructionOffset; - - /// - /// Writes an instruction - /// - /// The instruction writer - /// The instruction - protected virtual void WriteInstruction(ref ArrayWriter writer, Instruction instr) { - WriteOpCode(ref writer, instr); - WriteOperand(ref writer, instr); - } - - /// - /// Writes an instruction's opcode - /// - /// The instruction writer - /// 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 (hi == 0xFE || (hi >= 0xF0 && hi <= 0xFB)) { - writer.WriteByte((byte)((ushort)code >> 8)); - writer.WriteByte((byte)code); - } - else if (code == Code.UNKNOWN1) - writer.WriteByte((byte)Code.Nop); - else if (code == Code.UNKNOWN2) - writer.WriteUInt16((ushort)(((ushort)Code.Nop << 8) | Code.Nop)); - else { - Error("Unknown instruction"); - writer.WriteByte((byte)Code.Nop); - } - } - - /// - /// Writes an instruction's operand - /// - /// The instruction writer - /// The instruction - 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; - 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"); - break; - } - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineBrTarget(ref ArrayWriter writer, Instruction instr) { - uint displ = GetOffset(instr.Operand as Instruction) - (ToInstructionOffset(ref writer) + 4); - writer.WriteUInt32(displ); - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineField(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineI(ref ArrayWriter writer, Instruction instr) { - if (instr.Operand is int) - writer.WriteInt32((int)instr.Operand); - else { - Error("Operand is not an Int32"); - writer.WriteInt32(0); - } - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineI8(ref ArrayWriter writer, Instruction instr) { - if (instr.Operand is long) - writer.WriteInt64((long)instr.Operand); - else { - Error("Operand is not an Int64"); - writer.WriteInt64(0); - } - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineMethod(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineNone(ref ArrayWriter writer, Instruction instr) { - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlinePhi(ref ArrayWriter writer, Instruction instr) { - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineR(ref ArrayWriter writer, Instruction instr) { - if (instr.Operand is double) - writer.WriteDouble((double)instr.Operand); - else { - Error("Operand is not a Double"); - writer.WriteDouble(0); - } - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineSig(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineString(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineSwitch(ref ArrayWriter writer, Instruction instr) { - var targets = instr.Operand as IList; - if (targets is null) { - Error("switch operand is not a list of instructions"); - writer.WriteInt32(0); - } - else { - uint offsetAfter = (uint)(ToInstructionOffset(ref writer) + 4 + targets.Count * 4); - writer.WriteInt32(targets.Count); - for (int i = 0; i < targets.Count; i++) { - var target = targets[i]; - writer.WriteUInt32(GetOffset(target) - offsetAfter); - } - } - } - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineTok(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected abstract void WriteInlineType(ref ArrayWriter writer, Instruction instr); - - /// - /// Writes an operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteInlineVar(ref ArrayWriter writer, Instruction instr) { - var variable = instr.Operand as IVariable; - if (variable is null) { - Error("Operand is not a local/arg"); - writer.WriteUInt16(0); - } - else { - int index = variable.Index; - if (ushort.MinValue <= index && index <= ushort.MaxValue) - writer.WriteUInt16((ushort)index); - else { - Error("Local/arg index doesn't fit in a UInt16"); - writer.WriteUInt16(0); - } - } - } - - /// - /// Writes a operand - /// - /// Instruction writer - /// Instruction - 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.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.WriteByte(0); - } - } - - /// - /// Writes a operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteShortInlineI(ref ArrayWriter writer, Instruction instr) { - if (instr.Operand is sbyte) - writer.WriteSByte((sbyte)instr.Operand); - else if (instr.Operand is byte) - writer.WriteByte((byte)instr.Operand); - else { - Error("Operand is not a Byte or a SByte"); - writer.WriteByte(0); - } - } - - /// - /// Writes a operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteShortInlineR(ref ArrayWriter writer, Instruction instr) { - if (instr.Operand is float) - writer.WriteSingle((float)instr.Operand); - else { - Error("Operand is not a Single"); - writer.WriteSingle(0); - } - } - - /// - /// Writes a operand - /// - /// Instruction writer - /// Instruction - protected virtual void WriteShortInlineVar(ref ArrayWriter writer, Instruction instr) { - var variable = instr.Operand as IVariable; - if (variable is null) { - Error("Operand is not a local/arg"); - writer.WriteByte(0); - } - else { - int index = variable.Index; - if (byte.MinValue <= index && index <= byte.MaxValue) - writer.WriteByte((byte)index); - else { - Error("Local/arg index doesn't fit in a Byte. Use the longer ldloc/ldarg/stloc/starg instruction."); - writer.WriteByte(0); - } - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ModuleWriter.cs b/Plugins/dnlib/DotNet/Writer/ModuleWriter.cs deleted file mode 100644 index d4ade9a..0000000 --- a/Plugins/dnlib/DotNet/Writer/ModuleWriter.cs +++ /dev/null @@ -1,317 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.DotNet.MD; -using dnlib.PE; -using dnlib.W32Resources; - -namespace dnlib.DotNet.Writer { - /// - /// options - /// - public sealed class ModuleWriterOptions : ModuleWriterOptionsBase { - /// - /// Constructor - /// - /// The module - public ModuleWriterOptions(ModuleDef module) : base(module) { } - } - - /// - /// Writes a .NET PE file. See also - /// - public sealed class ModuleWriter : ModuleWriterBase { - const uint DEFAULT_RELOC_ALIGNMENT = 4; - const uint MVID_ALIGNMENT = 1; - - readonly ModuleDef module; - ModuleWriterOptions options; - - List sections; - PESection mvidSection; - PESection textSection; - PESection sdataSection; - PESection rsrcSection; - PESection relocSection; - - PEHeaders peHeaders; - ImportAddressTable importAddressTable; - ImageCor20Header imageCor20Header; - ImportDirectory importDirectory; - StartupStub startupStub; - RelocDirectory relocDirectory; - ManagedExportsWriter managedExportsWriter; - bool needStartupStub; - - /// - public override ModuleDef Module => module; - - /// - public override ModuleWriterOptionsBase TheOptions => Options; - - /// - /// Gets/sets the writer options. This is never null - /// - public ModuleWriterOptions Options { - get => options ??= new ModuleWriterOptions(module); - set => options = value; - } - - /// - /// 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 - /// - public override PESection TextSection => textSection; - - /// - /// Gets the .sdata section - /// - internal PESection SdataSection => sdataSection; - - /// - /// Gets the .rsrc section or null if none - /// - public override PESection RsrcSection => rsrcSection; - - /// - /// Gets the .reloc section - /// - public PESection RelocSection => relocSection; - - /// - /// Gets the PE headers - /// - public PEHeaders PEHeaders => peHeaders; - - /// - /// Gets the IAT or null if there's none - /// - public ImportAddressTable ImportAddressTable => importAddressTable; - - /// - /// Gets the .NET header - /// - public ImageCor20Header ImageCor20Header => imageCor20Header; - - /// - /// Gets the import directory or null if there's none - /// - public ImportDirectory ImportDirectory => importDirectory; - - /// - /// Gets the startup stub or null if there's none - /// - public StartupStub StartupStub => startupStub; - - /// - /// Gets the reloc directory or null if there's none - /// - public RelocDirectory RelocDirectory => relocDirectory; - - /// - /// Constructor - /// - /// The module - public ModuleWriter(ModuleDef module) - : this(module, null) { - } - - /// - /// Constructor - /// - /// The module - /// Options or null - public ModuleWriter(ModuleDef module, ModuleWriterOptions options) { - this.module = module; - this.options = options; - } - - /// - protected override long WriteImpl() { - Initialize(); - metadata.CreateTables(); - return WriteFile(); - } - - void Initialize() { - CreateSections(); - OnWriterEvent(ModuleWriterEvent.PESectionsCreated); - - CreateChunks(); - OnWriterEvent(ModuleWriterEvent.ChunksCreated); - - AddChunksToSections(); - OnWriterEvent(ModuleWriterEvent.ChunksAddedToSections); - } - - /// - protected override Win32Resources GetWin32Resources() { - if (Options.NoWin32Resources) - return null; - return Options.Win32Resources ?? module.Win32Resources; - } - - void CreateSections() { - sections = new List(); - if (TheOptions.AddMvidSection) - sections.Add(mvidSection = new PESection(".mvid", 0x42000040)); - sections.Add(textSection = new PESection(".text", 0x60000020)); - sections.Add(sdataSection = new PESection(".sdata", 0xC0000040)); - 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)); - } - - void CreateChunks() { - peHeaders = new PEHeaders(Options.PEHeadersOptions); - - var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; - bool is64bit = machine.Is64Bit(); - relocDirectory = new RelocDirectory(machine); - if (machine.IsI386()) - 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(); - - importDirectory.IsExeFile = Options.IsExeFile; - peHeaders.IsExeFile = Options.IsExeFile; - } - - void AddChunksToSections() { - var machine = Options.PEHeadersOptions.Machine ?? Machine.I386; - bool is64bit = machine.Is64Bit(); - uint pointerAlignment = is64bit ? 8U : 4; - - 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); - 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, pointerAlignment); - textSection.Add(startupStub, startupStub.Alignment); - managedExportsWriter.AddSdataChunks(sdataSection); - if (GetWin32Resources() is not null) - rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); - relocSection.Add(relocDirectory, DEFAULT_RELOC_ALIGNMENT); - } - - long WriteFile() { - managedExportsWriter.AddExportedMethods(metadata.ExportedMethods, GetTimeDateStamp()); - if (managedExportsWriter.HasExports) - needStartupStub = true; - - OnWriterEvent(ModuleWriterEvent.BeginWritePdb); - WritePdbFile(); - OnWriterEvent(ModuleWriterEvent.EndWritePdb); - - metadata.OnBeforeSetOffset(); - OnWriterEvent(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; - 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); - - InitializeChunkProperties(); - - OnWriterEvent(ModuleWriterEvent.BeginWriteChunks); - var writer = new DataWriter(destStream); - WriteChunks(writer, chunks, 0, peHeaders.FileAlignment); - long imageLength = writer.Position - destStreamBaseOffset; - OnWriterEvent(ModuleWriterEvent.EndWriteChunks); - - OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - if (Options.StrongNameKey is not null) - StrongNameSign((long)strongNameSignature.FileOffset); - OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); - - OnWriterEvent(ModuleWriterEvent.BeginWritePEChecksum); - if (Options.AddCheckSum) - peHeaders.WriteCheckSum(writer, imageLength); - OnWriterEvent(ModuleWriterEvent.EndWritePEChecksum); - - return imageLength; - } - - void InitializeChunkProperties() { - Options.Cor20HeaderOptions.EntryPoint = GetEntryPoint(); - - importAddressTable.ImportDirectory = importDirectory; - importDirectory.ImportAddressTable = importAddressTable; - startupStub.ImportDirectory = importDirectory; - startupStub.PEHeaders = peHeaders; - peHeaders.StartupStub = startupStub; - peHeaders.ImageCor20Header = imageCor20Header; - peHeaders.ImportAddressTable = importAddressTable; - peHeaders.ImportDirectory = importDirectory; - peHeaders.Win32Resources = win32Resources; - peHeaders.RelocDirectory = relocDirectory; - peHeaders.DebugDirectory = debugDirectory; - imageCor20Header.Metadata = metadata; - imageCor20Header.NetResources = netResources; - imageCor20Header.StrongNameSignature = strongNameSignature; - managedExportsWriter.InitializeChunkProperties(); - } - - uint GetEntryPoint() { - if (module.ManagedEntryPoint is MethodDef methodEntryPoint) - return new MDToken(Table.Method, metadata.GetRid(methodEntryPoint)).Raw; - - if (module.ManagedEntryPoint is FileDef fileEntryPoint) - return new MDToken(Table.File, metadata.GetRid(fileEntryPoint)).Raw; - - uint nativeEntryPoint = (uint)module.NativeEntryPoint; - if (nativeEntryPoint != 0) - return nativeEntryPoint; - - return 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ModuleWriterBase.cs b/Plugins/dnlib/DotNet/Writer/ModuleWriterBase.cs deleted file mode 100644 index e1b56d6..0000000 --- a/Plugins/dnlib/DotNet/Writer/ModuleWriterBase.cs +++ /dev/null @@ -1,1280 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using dnlib.IO; -using dnlib.DotNet.Pdb; -using dnlib.PE; -using dnlib.W32Resources; -using dnlib.DotNet.MD; -using System.Diagnostics; -using dnlib.DotNet.Pdb.WindowsPdb; -using System.Text; -using System.IO.Compression; -using System.Runtime.InteropServices; - -namespace dnlib.DotNet.Writer { - /// - /// Module writer event args - /// - public readonly struct ModuleWriterEventArgs { - /// - /// Gets the writer ( or ) - /// - public ModuleWriterBase Writer { get; } - - /// - /// Gets the event - /// - public ModuleWriterEvent Event { get; } - - /// - /// Constructor - /// - /// Writer - /// Event - public ModuleWriterEventArgs(ModuleWriterBase writer, ModuleWriterEvent @event) { - Writer = writer ?? throw new ArgumentNullException(nameof(writer)); - Event = @event; - } - } - - /// - /// Module writer progress event args - /// - public readonly struct ModuleWriterProgressEventArgs { - /// - /// 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; - } - } - - /// - /// 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; - } - } - - /// - /// Event handler - /// - /// Event args type - /// Sender - /// 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. - /// - /// 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, - } - - /// - /// Common module writer options base class - /// - public class ModuleWriterOptionsBase { - PEHeadersOptions peHeadersOptions; - Cor20HeaderOptions cor20HeaderOptions; - MetadataOptions metadataOptions; - ILogger logger; - ILogger metadataLogger; - bool noWin32Resources; - Win32Resources win32Resources; - StrongNameKey strongNameKey; - StrongNamePublicKey strongNamePublicKey; - bool delaySign; - - /// - /// 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 EventHandler2 WriterEvent; - internal void RaiseEvent(object sender, ModuleWriterEventArgs e) => WriterEvent?.Invoke(sender, e); - - /// - /// Raised when the progress is updated - /// - public event EventHandler2 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 - /// create your own logger or use . - /// - public ILogger Logger { - get => logger; - set => logger = value; - } - - /// - /// Gets/sets the writer logger. If this is null, use - /// . - /// - public ILogger MetadataLogger { - get => metadataLogger; - set => metadataLogger = value; - } - - /// - /// Gets/sets the options. This is never null. - /// - public PEHeadersOptions PEHeadersOptions { - get => peHeadersOptions ??= new PEHeadersOptions(); - set => peHeadersOptions = value; - } - - /// - /// Gets/sets the options. This is never null. - /// - public Cor20HeaderOptions Cor20HeaderOptions { - get => cor20HeaderOptions ??= new Cor20HeaderOptions(); - set => cor20HeaderOptions = value; - } - - /// - /// Gets/sets the options. This is never null. - /// - public MetadataOptions MetadataOptions { - get => metadataOptions ??= new 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. - /// - public Win32Resources Win32Resources { - get => 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 => 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. - /// You should call - /// to initialize this property if you use normal strong name signing. - /// You should call - /// or - /// to initialize this property if you use enhanced strong name signing. - /// - public StrongNameKey StrongNameKey { - get => strongNameKey; - set => strongNameKey = value; - } - - /// - /// Gets/sets the new public key that should be used. If this is null, use - /// the public key generated from . If it is also null, - /// use the module's Assembly's public key. - /// You should call - /// or - /// to initialize this property if you use enhanced strong name signing. - /// - public StrongNamePublicKey StrongNamePublicKey { - get => strongNamePublicKey; - set => strongNamePublicKey = value; - } - - /// - /// 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; } - - /// - /// true if the PE header CheckSum field should be updated, false if the - /// CheckSum field isn't updated. - /// - public bool AddCheckSum { get; set; } - - /// - /// true if it's a 64-bit module, false if it's a 32-bit or AnyCPU module. - /// - public bool Is64Bit { - get { - if (!PEHeadersOptions.Machine.HasValue) - return false; - return PEHeadersOptions.Machine.Value.Is64Bit(); - } - } - - /// - /// Gets/sets the module kind - /// - public ModuleKind ModuleKind { get; set; } - - /// - /// true if it should be written as an EXE file, false if it should be - /// written as a DLL file. - /// - 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 - /// won't be written to disk). - /// - 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 - /// this property is ignored. - /// - 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. - /// must be true or this property is ignored. - /// - public Stream PdbStream { get; set; } - - /// - /// 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. - /// - public Func GetPdbContentId { get; set; } - - const ChecksumAlgorithm DefaultPdbChecksumAlgorithm = ChecksumAlgorithm.SHA256; - - /// - /// PDB checksum algorithm - /// - public ChecksumAlgorithm PdbChecksumAlgorithm { get; set; } = DefaultPdbChecksumAlgorithm; - - /// - /// 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) { - ShareMethodBodies = true; - MetadataOptions.MetadataHeaderOptions.VersionString = module.RuntimeVersion; - ModuleKind = module.Kind; - PEHeadersOptions.Machine = module.Machine; - PEHeadersOptions.Characteristics = module.Characteristics; - PEHeadersOptions.DllCharacteristics = module.DllCharacteristics; - if (module.Kind == ModuleKind.Windows) - PEHeadersOptions.Subsystem = Subsystem.WindowsGui; - else - PEHeadersOptions.Subsystem = Subsystem.WindowsCui; - PEHeadersOptions.NumberOfRvaAndSizes = 0x10; - Cor20HeaderOptions.Flags = module.Cor20HeaderFlags; - - if (module.Assembly is not null && !PublicKeyBase.IsNullOrEmpty2(module.Assembly.PublicKey)) - Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; - - if (module.Cor20HeaderRuntimeVersion is not null) { - Cor20HeaderOptions.MajorRuntimeVersion = (ushort)(module.Cor20HeaderRuntimeVersion.Value >> 16); - Cor20HeaderOptions.MinorRuntimeVersion = (ushort)module.Cor20HeaderRuntimeVersion.Value; - } - else if (module.IsClr1x) { - Cor20HeaderOptions.MajorRuntimeVersion = 2; - Cor20HeaderOptions.MinorRuntimeVersion = 0; - } - else { - Cor20HeaderOptions.MajorRuntimeVersion = 2; - Cor20HeaderOptions.MinorRuntimeVersion = 5; - } - - if (module.TablesHeaderVersion is not null) { - MetadataOptions.TablesHeapOptions.MajorVersion = (byte)(module.TablesHeaderVersion.Value >> 8); - MetadataOptions.TablesHeapOptions.MinorVersion = (byte)module.TablesHeaderVersion.Value; - } - else if (module.IsClr1x) { - // Generics aren't supported - MetadataOptions.TablesHeapOptions.MajorVersion = 1; - MetadataOptions.TablesHeapOptions.MinorVersion = 0; - } - else { - // Generics are supported - MetadataOptions.TablesHeapOptions.MajorVersion = 2; - MetadataOptions.TablesHeapOptions.MinorVersion = 0; - } - - // Some tools crash if #GUID is missing so always create it by default - MetadataOptions.Flags |= MetadataFlags.AlwaysCreateGuidHeap; - - var modDefMD = module as ModuleDefMD; - if (modDefMD is not null) { - var ntHeaders = modDefMD.Metadata.PEImage.ImageNTHeaders; - PEHeadersOptions.TimeDateStamp = ntHeaders.FileHeader.TimeDateStamp; - 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; - AddMvidSection = HasMvidSection(modDefMD.Metadata.PEImage.ImageSectionHeaders); - 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; - MetadataOptions.TablesHeapOptions.Log2Rid = modDefMD.TablesStream.Log2Rid; - } - - if (Is64Bit) { - PEHeadersOptions.Characteristics &= ~Characteristics.Bit32Machine; - PEHeadersOptions.Characteristics |= Characteristics.LargeAddressAware; - } - else if (modDefMD is null) - PEHeadersOptions.Characteristics |= Characteristics.Bit32Machine; - } - - static bool HasMvidSection(IList 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; - // Roslyn ignores the last 2 bytes - if (name[0] == '.' && name[1] == 'm' && name[2] == 'v' && name[3] == 'i' && name[4] == 'd' && name[5] == 0) - return true; - } - return false; - } - - static bool HasDebugDirectoryEntry(IList debugDirs, ImageDebugType type) { - int count = debugDirs.Count; - for (int i = 0; i < count; i++) { - if (debugDirs[i].Type == type) - return true; - } - 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 (TryGetPdbChecksumAlgorithm(ref reader, out pdbChecksumAlgorithm)) - return true; - } - } - - pdbChecksumAlgorithm = DefaultPdbChecksumAlgorithm; - return false; - } - - static bool TryGetPdbChecksumAlgorithm(ref DataReader reader, out ChecksumAlgorithm pdbChecksumAlgorithm) { - try { - var checksumName = reader.TryReadZeroTerminatedUtf8String(); - 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. - /// - /// Module - /// Signature strong name key pair - public void InitializeStrongNameSigning(ModuleDef module, StrongNameKey signatureKey) { - StrongNameKey = signatureKey; - StrongNamePublicKey = null; - if (module.Assembly is not null) - module.Assembly.CustomAttributes.RemoveAll("System.Reflection.AssemblySignatureKeyAttribute"); - } - - /// - /// Initializes and - /// for enhanced strong name signing (without key migration). See - /// http://msdn.microsoft.com/en-us/library/hh415055.aspx - /// - /// Module - /// Signature strong name key pair - /// Signature public key - public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey signatureKey, StrongNamePublicKey signaturePubKey) { - InitializeStrongNameSigning(module, signatureKey); - StrongNameKey = StrongNameKey.WithHashAlgorithm(signaturePubKey.HashAlgorithm); - } - - /// - /// Initializes and - /// for enhanced strong name signing (with key migration). See - /// http://msdn.microsoft.com/en-us/library/hh415055.aspx - /// - /// Module - /// Signature strong name key pair - /// Signature public key - /// Identity strong name key pair - /// Identity public key - public void InitializeEnhancedStrongNameSigning(ModuleDef module, StrongNameKey signatureKey, StrongNamePublicKey signaturePubKey, StrongNameKey identityKey, StrongNamePublicKey identityPubKey) { - StrongNameKey = signatureKey.WithHashAlgorithm(signaturePubKey.HashAlgorithm); - StrongNamePublicKey = identityPubKey; - if (module.Assembly is not null) - module.Assembly.UpdateOrCreateAssemblySignatureKeyAttribute(identityPubKey, identityKey, signaturePubKey); - } - } - - /// - /// Module writer base class - /// - public abstract class ModuleWriterBase : ILogger { - /// Default alignment of all constants - protected internal const uint DEFAULT_CONSTANTS_ALIGNMENT = 8; - /// 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 = 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 = 4; - /// Default COR20 header alignment - protected const uint DEFAULT_COR20HEADER_ALIGNMENT = 4; - - /// See - protected Stream destStream; - /// See - protected UniqueChunkList constants; - /// See - protected MethodBodyChunks methodBodies; - /// See - protected NetResources netResources; - /// See - protected Metadata metadata; - /// See - protected Win32ResourcesChunk win32Resources; - /// Offset where the module is written. Usually 0. - protected long destStreamBaseOffset; - /// Debug directory - protected DebugDirectory debugDirectory; - - string createdPdbFileName; - - /// - /// Strong name signature - /// - protected StrongNameSignature strongNameSignature; - - /// - /// Returns the module writer options - /// - public abstract ModuleWriterOptionsBase TheOptions { get; } - - /// - /// Gets the destination stream - /// - public Stream DestinationStream => destStream; - - /// - /// Gets the constants - /// - public UniqueChunkList Constants => constants; - - /// - /// Gets the method bodies - /// - public MethodBodyChunks MethodBodies => methodBodies; - - /// - /// Gets the .NET resources - /// - public NetResources NetResources => netResources; - - /// - /// Gets the .NET metadata - /// - public Metadata Metadata => metadata; - - /// - /// Gets the Win32 resources or null if there's none - /// - public Win32ResourcesChunk Win32Resources => win32Resources; - - /// - /// Gets the strong name signature or null if there's none - /// - public StrongNameSignature StrongNameSignature => strongNameSignature; - - /// - /// 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 - /// - public abstract PESection TextSection { get; } - - /// - /// Gets the .rsrc section or null if there's none - /// - public abstract PESection RsrcSection { get; } - - /// - /// Gets the debug directory or null if there's none - /// - public DebugDirectory DebugDirectory => debugDirectory; - - /// - /// true if this is a , false if - /// this is a . - /// - public bool IsNativeWriter => this is NativeModuleWriter; - - /// - /// null if we're not writing a PDB - /// - PdbState pdbState; - - /// - /// Writes the module to a file - /// - /// File name. The file will be truncated if it exists. - public void Write(string fileName) { - using (var dest = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite)) { - dest.SetLength(0); - try { - Write(dest); - } - catch { - // Writing failed. Delete the file since it's useless. - dest.Close(); - DeleteFileNoThrow(fileName); - throw; - } - } - } - - static void DeleteFileNoThrow(string fileName) { - if (string.IsNullOrEmpty(fileName)) - return; - try { - File.Delete(fileName); - } - catch { - } - } - - /// - /// Writes the module to a - /// - /// Destination stream - public void Write(Stream dest) { - pdbState = TheOptions.WritePdb && Module.PdbState is not null ? Module.PdbState : null; - if (TheOptions.DelaySign) { - 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 not null || TheOptions.StrongNamePublicKey is not null) - TheOptions.Cor20HeaderOptions.Flags |= ComImageFlags.StrongNameSigned; - - destStream = dest; - destStreamBaseOffset = destStream.Position; - OnWriterEvent(ModuleWriterEvent.Begin); - var imageLength = WriteImpl(); - destStream.Position = destStreamBaseOffset + imageLength; - OnWriterEvent(ModuleWriterEvent.End); - } - - /// - /// Returns the module that is written - /// - public abstract ModuleDef Module { get; } - - /// - /// Writes the module to . Event listeners and - /// have been initialized when this method is called. - /// - /// Number of bytes written - protected abstract long WriteImpl(); - - /// - /// Creates the strong name signature if the module has one of the strong name flags - /// set or wants to sign the assembly. - /// - protected void CreateStrongNameSignature() { - 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 not null) - strongNameSignature = new StrongNameSignature(TheOptions.StrongNameKey.SignatureSize); - 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); - } - else if (((TheOptions.Cor20HeaderOptions.Flags ?? Module.Cor20HeaderFlags) & ComImageFlags.StrongNameSigned) != 0) - strongNameSignature = new StrongNameSignature(0x80); - } - - /// - /// Creates the .NET metadata chunks (constants, method bodies, .NET resources, - /// the metadata, and Win32 resources) - /// - /// - protected void CreateMetadataChunks(ModuleDef module) { - constants = new UniqueChunkList(); - methodBodies = new MethodBodyChunks(TheOptions.ShareMethodBodies); - netResources = new NetResources(DEFAULT_NETRESOURCES_ALIGNMENT); - - DebugMetadataKind debugKind; - if (pdbState is not 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.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. - var pk = TheOptions.StrongNamePublicKey; - if (pk is not null) - metadata.AssemblyPublicKey = pk.CreatePublicKey(); - else if (TheOptions.StrongNameKey is not null) - metadata.AssemblyPublicKey = TheOptions.StrongNameKey.PublicKey; - - var w32Resources = GetWin32Resources(); - if (w32Resources is not null) - win32Resources = new Win32ResourcesChunk(w32Resources); - } - - /// - /// Gets the Win32 resources that should be written to the new image or null if none - /// - protected abstract Win32Resources GetWin32Resources(); - - /// - /// Calculates and of all s - /// - /// All chunks - /// Starting file offset - /// Starting RVA - /// File alignment - /// 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]; - // 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) { - offset += chunk.GetFileLength(); - rva += chunk.GetVirtualSize(); - offset = offset.AlignUp(fileAlignment); - rva = rva.AlignUp(sectionAlignment); - } - } - } - - /// - /// Writes all chunks to - /// - /// The writer - /// All chunks - /// File offset of first chunk - /// File alignment - protected void WriteChunks(DataWriter writer, List chunks, FileOffset offset, uint fileAlignment) { - 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) { - offset += chunk.GetFileLength(); - var newOffset = offset.AlignUp(fileAlignment); - writer.WriteZeroes((int)(newOffset - offset)); - offset = newOffset; - } - } - } - - /// - /// Strong name sign the assembly - /// - /// Strong name signature offset - protected void StrongNameSign(long snSigOffset) { - var snSigner = new StrongNameSigner(destStream, destStreamBaseOffset); - snSigner.WriteSignature(TheOptions.StrongNameKey, snSigOffset); - } - - bool CanWritePdb() => pdbState is not null; - - /// - /// Creates the debug directory if a PDB file should be written - /// - protected void CreateDebugDirectory() { - if (CanWritePdb()) - debugDirectory = new DebugDirectory(); - } - - /// - /// Write the PDB file. The caller should send the PDB events before and after calling this - /// method. - /// - protected void WritePdbFile() { - if (!CanWritePdb()) - return; - if (debugDirectory is null) - throw new InvalidOperationException("debugDirectory is null but WritePdb is true"); - - if (pdbState is null) { - Error("TheOptions.WritePdb is true but module has no PdbState"); - return; - } - - 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 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); - } - - const uint PdbAge = 1; - 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 is null) { - Error("Could not create a PDB symbol writer. A Windows OS might be required."); - return; - } - - using (var pdbWriter = new WindowsPdbWriter(symWriter, pdbState, metadata)) { - pdbWriter.Logger = TheOptions.Logger; - pdbWriter.Write(); - - 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, TheOptions.PdbFileNameInDebugDirectory ?? pdbFilename), - type: ImageDebugType.CodeView, - majorVersion: 0, - minorVersion: 0, - timeDateStamp: stamp); - } - else { - Debug.Fail("Failed to get the PDB content ID"); - if (codeViewData is 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 (symWriter.IsDeterministic) - AddReproduciblePdbDebugDirectoryEntry(); - } - } - - /// - /// Gets the timestamp stored in the PE header - /// - /// - protected uint GetTimeDateStamp() { - var td = TheOptions.PEHeadersOptions.TimeDateStamp; - if (td.HasValue) - return (uint)td; - TheOptions.PEHeadersOptions.TimeDateStamp = PEHeadersOptions.CreateNewTimeDateStamp(); - return (uint)TheOptions.PEHeadersOptions.TimeDateStamp; - } - - 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 ?? - GetStreamName(TheOptions.PdbStream) ?? - GetDefaultPdbFileName()); - } - - if (!string.IsNullOrEmpty(TheOptions.PdbFileName)) { - createdPdbFileName = pdbFilename = TheOptions.PdbFileName; - return Pdb.Dss.SymbolReaderWriterFactory.Create(options, createdPdbFileName); - } - - createdPdbFileName = pdbFilename = GetDefaultPdbFileName(); - if (createdPdbFileName is null) - return null; - return Pdb.Dss.SymbolReaderWriterFactory.Create(options, createdPdbFileName); - } - - static string GetStreamName(Stream stream) => (stream as FileStream)?.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) ?? 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; - } - - 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); - if (pdbStream is null) - throw new ModuleWriterException("Couldn't create a PDB stream"); - - var pdbFilename = TheOptions.PdbFileName ?? GetStreamName(pdbStream) ?? GetDefaultPdbFileName(); - if (isEmbeddedPortablePdb) - pdbFilename = Path.GetFileName(pdbFilename); - - uint entryPointToken; - if (pdbState.UserEntryPoint is null) - entryPointToken = 0; - 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 ArrayWriter(pdbId); - uint codeViewTimestamp; - byte[] checksumBytes; - if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0 || - (TheOptions.PdbOptions & PdbWriterOptions.PdbChecksum) != 0 || - TheOptions.GetPdbContentId is null) { - pdbStream.Position = 0; - 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 { - var contentId = TheOptions.GetPdbContentId(pdbStream, GetTimeDateStamp()); - codeViewTimestamp = contentId.Timestamp; - pdbGuid = contentId.Guid; - checksumBytes = null; - } - pdbIdWriter.WriteBytes(pdbGuid.ToByteArray()); - pdbIdWriter.WriteUInt32(codeViewTimestamp); - Debug.Assert(pdbIdWriter.Position == pdbId.Length); - pdbStream.Position = pdbIdOffset; - pdbStream.Write(pdbId, 0, pdbId.Length); - - // NOTE: We add these directory entries in the same order as Roslyn seems to do: - // - CodeView - // - PdbChecksum - // - Reproducible - // - EmbeddedPortablePdb - - debugDirectory.Add(GetCodeViewData(pdbGuid, PdbAge, TheOptions.PdbFileNameInDebugDirectory ?? pdbFilename), - type: ImageDebugType.CodeView, - majorVersion: PortablePdbConstants.FormatVersion, - minorVersion: PortablePdbConstants.PortableCodeViewVersionMagic, - timeDateStamp: codeViewTimestamp); - - if (checksumBytes is not null) - AddPdbChecksumDebugDirectoryEntry(checksumBytes, TheOptions.PdbChecksumAlgorithm); - - if ((TheOptions.PdbOptions & PdbWriterOptions.Deterministic) != 0) - AddReproduciblePdbDebugDirectoryEntry(); - - if (isEmbeddedPortablePdb) { - Debug.Assert(embeddedMemoryStream is not null); - debugDirectory.Add(CreateEmbeddedPortablePdbBlob(embeddedMemoryStream), - type: ImageDebugType.EmbeddedPortablePdb, - majorVersion: PortablePdbConstants.FormatVersion, - minorVersion: PortablePdbConstants.EmbeddedVersion, - timeDateStamp: 0); - } - } - finally { - if (ownsStream && pdbStream is not 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 DataWriter(stream); - writer.WriteInt32(0x4244504D);//"MPDB" - writer.WriteUInt32((uint)portablePdbStream.Length); - writer.WriteBytes(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 DataWriter(stream); - writer.WriteInt32(0x53445352); - writer.WriteBytes(guid.ToByteArray()); - writer.WriteUInt32(age); - writer.WriteBytes(Encoding.UTF8.GetBytes(filename)); - writer.WriteByte(0); - return stream.ToArray(); - } - - Stream GetStandalonePortablePdbStream(out bool ownsStream) { - if (TheOptions.PdbStream is not null) { - ownsStream = false; - return TheOptions.PdbStream; - } - - if (!string.IsNullOrEmpty(TheOptions.PdbFileName)) - createdPdbFileName = TheOptions.PdbFileName; - else - createdPdbFileName = GetDefaultPdbFileName(); - if (createdPdbFileName is null) { - ownsStream = false; - return null; - } - ownsStream = true; - return File.Create(createdPdbFileName); - } - - void Metadata_MetadataEvent(object sender, MetadataWriterEventArgs e) { - switch (e.Event) { - case MetadataEvent.BeginCreateTables: - OnWriterEvent(ModuleWriterEvent.MDBeginCreateTables); - break; - - case MetadataEvent.AllocateTypeDefRids: - OnWriterEvent(ModuleWriterEvent.MDAllocateTypeDefRids); - break; - - case MetadataEvent.AllocateMemberDefRids: - OnWriterEvent(ModuleWriterEvent.MDAllocateMemberDefRids); - break; - - case MetadataEvent.MemberDefRidsAllocated: - OnWriterEvent(ModuleWriterEvent.MDMemberDefRidsAllocated); - break; - - case MetadataEvent.MemberDefsInitialized: - OnWriterEvent(ModuleWriterEvent.MDMemberDefsInitialized); - break; - - case MetadataEvent.BeforeSortTables: - OnWriterEvent(ModuleWriterEvent.MDBeforeSortTables); - break; - - case MetadataEvent.MostTablesSorted: - OnWriterEvent(ModuleWriterEvent.MDMostTablesSorted); - break; - - case MetadataEvent.MemberDefCustomAttributesWritten: - OnWriterEvent(ModuleWriterEvent.MDMemberDefCustomAttributesWritten); - break; - - case MetadataEvent.BeginAddResources: - OnWriterEvent(ModuleWriterEvent.MDBeginAddResources); - break; - - case MetadataEvent.EndAddResources: - OnWriterEvent(ModuleWriterEvent.MDEndAddResources); - break; - - case MetadataEvent.BeginWriteMethodBodies: - OnWriterEvent(ModuleWriterEvent.MDBeginWriteMethodBodies); - break; - - case MetadataEvent.EndWriteMethodBodies: - OnWriterEvent(ModuleWriterEvent.MDEndWriteMethodBodies); - break; - - case MetadataEvent.OnAllTablesSorted: - OnWriterEvent(ModuleWriterEvent.MDOnAllTablesSorted); - break; - - case MetadataEvent.EndCreateTables: - OnWriterEvent(ModuleWriterEvent.MDEndCreateTables); - 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) { - 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; - - /// - void ILogger.Log(object sender, LoggerEvent loggerEvent, string format, params object[] args) => - GetLogger().Log(this, loggerEvent, format, args); - - /// - bool ILogger.IgnoresEvent(LoggerEvent loggerEvent) => GetLogger().IgnoresEvent(loggerEvent); - - /// - /// Logs an error message - /// - /// Format - /// Format 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) => - GetLogger().Log(this, LoggerEvent.Warning, format, args); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ModuleWriterEvent.cs b/Plugins/dnlib/DotNet/Writer/ModuleWriterEvent.cs deleted file mode 100644 index ee4dca0..0000000 --- a/Plugins/dnlib/DotNet/Writer/ModuleWriterEvent.cs +++ /dev/null @@ -1,180 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - /// - /// All / events - /// - public enum ModuleWriterEvent { - /// - /// Writing has just begun - /// - Begin, - - /// - /// All PE sections have been created - /// - PESectionsCreated, - - /// - /// All chunks have been created - /// - ChunksCreated, - - /// - /// All chunks have been added to their sections - /// - ChunksAddedToSections, - - /// - /// Original event: . - /// Creating the metadata tables has just begun - /// - MDBeginCreateTables, - - /// - /// Original event: . - /// Before allocating all TypeDef RIDs - /// - MDAllocateTypeDefRids, - - /// - /// Original event: . - /// Before allocating all MemberDef RIDs - /// - MDAllocateMemberDefRids, - - /// - /// Original event: . - /// The rids of types, fields, methods, events, properties and parameters are - /// now known. - /// - MDMemberDefRidsAllocated, - - /// - /// Original event: . - /// 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 - /// written yet. - /// - MDMemberDefsInitialized, - - /// - /// Original event: . - /// Before sorting most tables - /// - MDBeforeSortTables, - - /// - /// Original event: . - /// Most of the tables that should be sorted have been sorted. The CustomAttribute - /// table is still unsorted since it hasn't been created yet. - /// - MDMostTablesSorted, - - /// - /// Original event: . - /// Custom attributes of all types, fields, methods, events, properties and parameters - /// have now been written. - /// - MDMemberDefCustomAttributesWritten, - - /// - /// Original event: . - /// All resources are about to be added to the .NET resources table - /// - MDBeginAddResources, - - /// - /// Original event: . - /// All resources have been added to the .NET resources table - /// - MDEndAddResources, - - /// - /// Original event: . - /// All method bodies are about to be written - /// - MDBeginWriteMethodBodies, - - /// - /// Original event: . - /// All method bodies have been written. Their RVAs are still not known. - /// - MDEndWriteMethodBodies, - - /// - /// Original event: . - /// All tables are now sorted, including the CustomAttribute table. - /// - MDOnAllTablesSorted, - - /// - /// Original event: . - /// All tables have been created and all rows populated. The only columns that haven't - /// been initialized yet are the ones that are RVAs. - /// - MDEndCreateTables, - - /// - /// This event occurs before the PDB file is written. This event occurs even if no PDB file - /// will be written. - /// - BeginWritePdb, - - /// - /// The PDB file has been written. This event occurs even if no PDB file has been written. - /// - EndWritePdb, - - /// - /// This event occurs just before all RVAs and file offsets of the chunks are calculated. - /// - BeginCalculateRvasAndFileOffsets, - - /// - /// File offsets and RVAs of all chunks are now known. This includes method body and - /// field RVAs. Nothing has been written to the destination stream yet. - /// - EndCalculateRvasAndFileOffsets, - - /// - /// This event occurs before all chunks are written to the destination stream, and after - /// all RVAs and file offsets are known. - /// - BeginWriteChunks, - - /// - /// All chunks have been written to the destination stream. - /// - EndWriteChunks, - - /// - /// This event occurs before the strong name signature is calculated. This event - /// occurs even if the assembly isn't strong name signed. - /// - BeginStrongNameSign, - - /// - /// This event occurs after the strong name signature has been calculated. This event - /// occurs even if the assembly isn't strong name signed. - /// - EndStrongNameSign, - - /// - /// This event occurs before the checksum in the PE header is updated. This event - /// occurs even if the checksum isn't updated. - /// - BeginWritePEChecksum, - - /// - /// This event occurs after the checksum in the PE header has been updated. This event - /// occurs even if the checksum isn't updated. - /// - EndWritePEChecksum, - - /// - /// Writing has ended - /// - End, - } -} diff --git a/Plugins/dnlib/DotNet/Writer/ModuleWriterException.cs b/Plugins/dnlib/DotNet/Writer/ModuleWriterException.cs deleted file mode 100644 index 2014713..0000000 --- a/Plugins/dnlib/DotNet/Writer/ModuleWriterException.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.Serialization; - -namespace dnlib.DotNet.Writer { - /// - /// Thrown when the module writer encounters an unrecoverable error - /// - [Serializable] - public class ModuleWriterException : Exception { - /// - /// Default constructor - /// - public ModuleWriterException() { - } - - /// - /// Constructor - /// - /// Error message - public ModuleWriterException(string message) - : base(message) { - } - - /// - /// Constructor - /// - /// Error message - /// Other exception - public ModuleWriterException(string message, Exception innerException) - : base(message, innerException) { - } - - /// - /// Constructor - /// - /// - /// - protected ModuleWriterException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/NativeModuleWriter.cs b/Plugins/dnlib/DotNet/Writer/NativeModuleWriter.cs deleted file mode 100644 index df61a81..0000000 --- a/Plugins/dnlib/DotNet/Writer/NativeModuleWriter.cs +++ /dev/null @@ -1,844 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; -using dnlib.W32Resources; -using dnlib.DotNet.MD; -using System.Diagnostics; - -namespace dnlib.DotNet.Writer { - /// - /// options - /// - public sealed class NativeModuleWriterOptions : ModuleWriterOptionsBase { - /// - /// If true, any extra data after the PE data in the original file is also saved - /// at the end of the new file. Enable this option if some protector has written data to - /// the end of the file and uses it at runtime. - /// - public bool KeepExtraPEData { get; set; } - - /// - /// If true, keep the original Win32 resources - /// - public bool KeepWin32Resources { get; set; } - - internal bool OptimizeImageSize { get; } - - /// - /// Constructor - /// - /// 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; - } - } - } - - /// - /// A module writer that supports saving mixed-mode modules (modules with native code). - /// The original image will be re-used. See also - /// - public sealed class NativeModuleWriter : ModuleWriterBase { - /// The original .NET module - readonly ModuleDefMD module; - - /// All options - NativeModuleWriterOptions options; - - /// - /// Any extra data found at the end of the original file. This is null if there's - /// no extra data or if is - /// false. - /// - DataReaderChunk extraData; - - /// 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; - - /// New sections we've added and their data - List sections; - - /// New .text section where we put some stuff, eg. .NET metadata - PESection textSection; - - /// The new COR20 header - ByteArrayChunk imageCor20Header; - - /// - /// New .rsrc section where we put the new Win32 resources. This is null if there - /// are no Win32 resources or if - /// is true - /// - PESection rsrcSection; - - /// - /// Offset in of the PE checksum field. - /// - long checkSumOffset; - - /// - /// Original PE section - /// - public sealed class OrigSection : IDisposable { - /// PE section - public ImageSectionHeader PESection; - /// PE section data - public DataReaderChunk Chunk; - - /// - /// Constructor - /// - /// PE section - public OrigSection(ImageSectionHeader peSection) => - PESection = peSection; - - /// - public void Dispose() { - Chunk = null; - PESection = null; - } - - /// - public override string ToString() { - uint offs = Chunk.CreateReader().StartOffset; - return $"{PESection.DisplayName} FO:{offs:X8} L:{Chunk.CreateReader().Length:X8}"; - } - } - - /// - /// Gets the module - /// - public ModuleDefMD ModuleDefMD => module; - - /// - public override ModuleDef Module => module; - - /// - public override ModuleWriterOptionsBase TheOptions => Options; - - /// - /// Gets/sets the writer options. This is never null - /// - public NativeModuleWriterOptions Options { - get => options ??= new NativeModuleWriterOptions(module, optimizeImageSize: true); - set => options = value; - } - - /// - /// Gets all s - /// - public override List Sections => sections; - - /// - /// Gets the original PE sections and their data - /// - public List OrigSections => origSections; - - /// - /// Gets the .text section - /// - public override PESection TextSection => textSection; - - /// - /// Gets the .rsrc section or null if there's none - /// - public override PESection RsrcSection => rsrcSection; - - /// - /// Constructor - /// - /// The module - /// Options or null - public NativeModuleWriter(ModuleDefMD module, NativeModuleWriterOptions options) { - this.module = module; - this.options = options; - peImage = module.Metadata.PEImage; - reusedChunks = new List(); - } - - /// - protected override long WriteImpl() { - try { - return Write(); - } - finally { - if (origSections is not null) { - foreach (var section in origSections) - section.Dispose(); - } - } - } - - long Write() { - Initialize(); - - // It's not safe to create new Field RVAs so re-use them all. The user can override - // this by setting field.RVA = 0 when creating a new field.InitialValue. - metadata.KeepFieldRVA = true; - - metadata.CreateTables(); - return WriteFile(); - } - - void Initialize() { - CreateSections(); - OnWriterEvent(ModuleWriterEvent.PESectionsCreated); - - CreateChunks(); - OnWriterEvent(ModuleWriterEvent.ChunksCreated); - - AddChunksToSections(); - OnWriterEvent(ModuleWriterEvent.ChunksAddedToSections); - } - - void CreateSections() { - CreatePESections(); - CreateRawSections(); - CreateExtraData(); - } - - void CreateChunks() { - CreateMetadataChunks(module); - methodBodies.CanReuseOldBodyLocation = Options.OptimizeImageSize; - - CreateDebugDirectory(); - - imageCor20Header = new ByteArrayChunk(new byte[0x48]); - CreateStrongNameSignature(); - } - - void AddChunksToSections() { - textSection.Add(imageCor20Header, DEFAULT_COR20HEADER_ALIGNMENT); - textSection.Add(strongNameSignature, DEFAULT_STRONGNAMESIG_ALIGNMENT); - 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); - if (rsrcSection is not null) - rsrcSection.Add(win32Resources, DEFAULT_WIN32_RESOURCES_ALIGNMENT); - } - - /// - protected override Win32Resources GetWin32Resources() { - if (Options.KeepWin32Resources) - return null; - if (Options.NoWin32Resources) - return null; - return Options.Win32Resources ?? module.Win32Resources; - } - - void CreatePESections() { - sections = new List(); - sections.Add(textSection = new PESection(".text", 0x60000020)); - if (GetWin32Resources() is not null) - sections.Add(rsrcSection = new PESection(".rsrc", 0x40000040)); - } - - /// - /// Gets the raw section data of the image. The sections are saved in - /// . - /// - void CreateRawSections() { - var fileAlignment = peImage.ImageNTHeaders.OptionalHeader.FileAlignment; - origSections = new List(peImage.ImageSectionHeaders.Count); - - foreach (var peSection in peImage.ImageSectionHeaders) { - var newSection = new OrigSection(peSection); - origSections.Add(newSection); - uint sectionSize = Utils.AlignUp(peSection.SizeOfRawData, fileAlignment); - newSection.Chunk = new DataReaderChunk(peImage.CreateReader(peSection.VirtualAddress, sectionSize), peSection.VirtualSize); - } - } - - /// - /// Creates the PE header "section" - /// - DataReaderChunk CreateHeaderSection(out IChunk extraHeaderData) { - uint afterLastSectHeader = GetOffsetAfterLastSectionHeader() + (uint)sections.Count * 0x28; - uint firstRawOffset = Math.Min(GetFirstRawDataFileOffset(), peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); - uint headerLen = afterLastSectHeader; - if (firstRawOffset > headerLen) - headerLen = firstRawOffset; - headerLen = Utils.AlignUp(headerLen, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); - if (headerLen <= peImage.ImageNTHeaders.OptionalHeader.SectionAlignment) { - 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 - throw new ModuleWriterException("Could not create header"); - } - - uint GetOffsetAfterLastSectionHeader() { - var lastSect = peImage.ImageSectionHeaders[peImage.ImageSectionHeaders.Count - 1]; - return (uint)lastSect.EndOffset; - } - - uint GetFirstRawDataFileOffset() { - uint len = uint.MaxValue; - foreach (var section in peImage.ImageSectionHeaders) - len = Math.Min(len, section.PointerToRawData); - return len; - } - - /// - /// Saves any data that is appended to the original PE file - /// - void CreateExtraData() { - if (!Options.KeepExtraPEData) - return; - var lastOffs = GetLastFileSectionOffset(); - extraData = new DataReaderChunk(peImage.CreateReader((FileOffset)lastOffs)); - if (extraData.CreateReader().Length == 0) - extraData = null; - } - - uint GetLastFileSectionOffset() { - uint rva = 0; - foreach (var sect in origSections) - rva = Math.Max(rva, (uint)sect.PESection.VirtualAddress + sect.PESection.SizeOfRawData); - 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 is null) - return; - if (!chunk.CanReuse(origRva, origSize)) - return; - if (((uint)origRva & (requiredAlignment - 1)) != 0) - return; - - if (section.Remove(chunk) is null) - throw new InvalidOperationException(); - 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); - - OnWriterEvent(ModuleWriterEvent.BeginWritePdb); - WritePdbFile(); - OnWriterEvent(ModuleWriterEvent.EndWritePdb); - - metadata.OnBeforeSetOffset(); - 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 is not 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 is not null && rsrcSection.IsEmpty) { - sections.Remove(rsrcSection); - rsrcSection = null; - } - - var headerSection = CreateHeaderSection(out var extraHeaderData); - var chunks = new List(); - uint headerLen; - if (extraHeaderData is not 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) - chunks.Add(section); - if (extraData is not null) - chunks.Add(extraData); - - CalculateRvasAndFileOffsets(chunks, 0, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment, peImage.ImageNTHeaders.OptionalHeader.SectionAlignment); - if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { - methodBodies.InitializeReusedMethodBodies(GetNewFileOffset); - foreach (var info in reusedChunks) { - var offset = GetNewFileOffset(info.RVA); - info.Chunk.SetOffset(offset, info.RVA); - } - } - metadata.UpdateMethodAndFieldRvas(); - foreach (var section in origSections) { - if (section.Chunk.RVA != section.PESection.VirtualAddress) - throw new ModuleWriterException("Invalid section RVA"); - } - OnWriterEvent(ModuleWriterEvent.EndCalculateRvasAndFileOffsets); - - OnWriterEvent(ModuleWriterEvent.BeginWriteChunks); - var writer = new DataWriter(destStream); - WriteChunks(writer, chunks, 0, peImage.ImageNTHeaders.OptionalHeader.FileAlignment); - long imageLength = writer.Position - destStreamBaseOffset; - if (reusedChunks.Count > 0 || methodBodies.HasReusedMethods) { - 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.Position = destStreamBaseOffset + (uint)info.Chunk.FileOffset; - info.Chunk.VerifyWriteTo(writer); - } - methodBodies.WriteReusedMethodBodies(writer, destStreamBaseOffset); - writer.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); - if (Options.StrongNameKey is not null) - StrongNameSign((long)strongNameSignature.FileOffset); - OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); - - OnWriterEvent(ModuleWriterEvent.BeginWritePEChecksum); - if (Options.AddCheckSum) { - destStream.Position = destStreamBaseOffset; - uint newCheckSum = destStream.CalculatePECheckSum(imageLength, checkSumOffset); - writer.Position = checkSumOffset; - writer.WriteUInt32(newCheckSum); - } - OnWriterEvent(ModuleWriterEvent.EndWritePEChecksum); - - 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]; - var prevEnd = (uint)debugDataDir.VirtualAddress + debugDataDir.Size; - for (int i = 0; i < dirs.Count; i++) { - uint prevEndAligned = (prevEnd + 3) & ~3U; - 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 = prevEnd - (uint)debugDataDir.VirtualAddress; - return true; - } - - /// - /// true if image is 64-bit - /// - bool Is64Bit() => peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader64; - - Characteristics GetCharacteristics() { - var ch = module.Characteristics; - if (Is64Bit()) - ch &= ~Characteristics.Bit32Machine; - else - ch |= Characteristics.Bit32Machine; - if (Options.IsExeFile) - ch &= ~Characteristics.Dll; - else - ch |= Characteristics.Dll; - return ch; - } - - /// - /// Updates the PE header and COR20 header fields that need updating. All sections are - /// also updated, and the new ones are added. - /// - 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; - long dataDirOffset = destStreamBaseOffset + (long)peImage.ImageNTHeaders.OptionalHeader.EndOffset - 16 * 8; - long cor20Offset = destStreamBaseOffset + (long)imageCor20Header.FileOffset; - - // Update PE file header - var peOptions = Options.PEHeadersOptions; - writer.Position = fileHeaderOffset; - 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.WriteUInt16((ushort)(peOptions.Characteristics ?? GetCharacteristics())); - - // Update optional header - writer.Position = optionalHeaderOffset; - bool is32BitOptionalHeader = peImage.ImageNTHeaders.OptionalHeader is ImageOptionalHeader32; - if (is32BitOptionalHeader) { - writer.Position += 2; - WriteByte(writer, peOptions.MajorLinkerVersion); - WriteByte(writer, peOptions.MinorLinkerVersion); - writer.WriteUInt32(sectionSizes.SizeOfCode); - writer.WriteUInt32(sectionSizes.SizeOfInitdData); - writer.WriteUInt32(sectionSizes.SizeOfUninitdData); - writer.Position += 4; // EntryPoint - writer.WriteUInt32(sectionSizes.BaseOfCode); - writer.WriteUInt32(sectionSizes.BaseOfData); - WriteUInt32(writer, peOptions.ImageBase); - writer.Position += 8; // SectionAlignment, FileAlignment - WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); - WriteUInt16(writer, peOptions.MinorOperatingSystemVersion); - WriteUInt16(writer, peOptions.MajorImageVersion); - WriteUInt16(writer, peOptions.MinorImageVersion); - WriteUInt16(writer, peOptions.MajorSubsystemVersion); - WriteUInt16(writer, peOptions.MinorSubsystemVersion); - WriteUInt32(writer, peOptions.Win32VersionValue); - writer.WriteUInt32(sectionSizes.SizeOfImage); - writer.WriteUInt32(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.Position; - writer.WriteInt32(0); // CheckSum - WriteUInt16(writer, peOptions.Subsystem); - WriteUInt16(writer, peOptions.DllCharacteristics); - WriteUInt32(writer, peOptions.SizeOfStackReserve); - WriteUInt32(writer, peOptions.SizeOfStackCommit); - WriteUInt32(writer, peOptions.SizeOfHeapReserve); - WriteUInt32(writer, peOptions.SizeOfHeapCommit); - WriteUInt32(writer, peOptions.LoaderFlags); - WriteUInt32(writer, peOptions.NumberOfRvaAndSizes); - } - else { - writer.Position += 2; - WriteByte(writer, peOptions.MajorLinkerVersion); - WriteByte(writer, peOptions.MinorLinkerVersion); - writer.WriteUInt32(sectionSizes.SizeOfCode); - writer.WriteUInt32(sectionSizes.SizeOfInitdData); - writer.WriteUInt32(sectionSizes.SizeOfUninitdData); - writer.Position += 4; // EntryPoint - writer.WriteUInt32(sectionSizes.BaseOfCode); - WriteUInt64(writer, peOptions.ImageBase); - writer.Position += 8; // SectionAlignment, FileAlignment - WriteUInt16(writer, peOptions.MajorOperatingSystemVersion); - WriteUInt16(writer, peOptions.MinorOperatingSystemVersion); - WriteUInt16(writer, peOptions.MajorImageVersion); - WriteUInt16(writer, peOptions.MinorImageVersion); - WriteUInt16(writer, peOptions.MajorSubsystemVersion); - WriteUInt16(writer, peOptions.MinorSubsystemVersion); - WriteUInt32(writer, peOptions.Win32VersionValue); - writer.WriteUInt32(sectionSizes.SizeOfImage); - writer.WriteUInt32(sectionSizes.SizeOfHeaders); - checkSumOffset = writer.Position; - writer.WriteInt32(0); // CheckSum - WriteUInt16(writer, peOptions.Subsystem ?? GetSubsystem()); - WriteUInt16(writer, peOptions.DllCharacteristics ?? module.DllCharacteristics); - WriteUInt64(writer, peOptions.SizeOfStackReserve); - WriteUInt64(writer, peOptions.SizeOfStackCommit); - WriteUInt64(writer, peOptions.SizeOfHeapReserve); - WriteUInt64(writer, peOptions.SizeOfHeapCommit); - WriteUInt32(writer, peOptions.LoaderFlags); - WriteUInt32(writer, peOptions.NumberOfRvaAndSizes); - } - - // Update Win32 resources data directory, if we wrote a new one - if (win32Resources is not null) { - writer.Position = dataDirOffset + 2 * 8; - writer.WriteDataDirectory(win32Resources); - } - - // Clear the security descriptor directory - writer.Position = dataDirOffset + 4 * 8; - writer.WriteDataDirectory(null); - - // Write a new debug directory - writer.Position = dataDirOffset + 6 * 8; - writer.WriteDebugDirectory(debugDirectory); - - // Write a new Metadata data directory - writer.Position = dataDirOffset + 14 * 8; - writer.WriteDataDirectory(imageCor20Header); - - // Update old sections, and add new sections - writer.Position = sectionsOffset; - foreach (var section in origSections) { - writer.Position += 0x14; - writer.WriteUInt32((uint)section.Chunk.FileOffset); // PointerToRawData - 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.Position = cor20Offset; - writer.WriteInt32(0x48); // cb - WriteUInt16(writer, Options.Cor20HeaderOptions.MajorRuntimeVersion); - WriteUInt16(writer, Options.Cor20HeaderOptions.MinorRuntimeVersion); - writer.WriteDataDirectory(metadata); - writer.WriteUInt32((uint)GetComImageFlags(entryPointIsManagedOrNoEntryPoint)); - writer.WriteUInt32(entryPointToken); - writer.WriteDataDirectory(netResources); - writer.WriteDataDirectory(strongNameSignature); - WriteDataDirectory(writer, module.Metadata.ImageCor20Header.CodeManagerTable); - WriteDataDirectory(writer, module.Metadata.ImageCor20Header.VTableFixups); - WriteDataDirectory(writer, module.Metadata.ImageCor20Header.ExportAddressTableJumps); - WriteDataDirectory(writer, module.Metadata.ImageCor20Header.ManagedNativeHeader); - - UpdateVTableFixups(writer); - } - - static void WriteDataDirectory(DataWriter writer, ImageDataDirectory dataDir) { - writer.WriteUInt32((uint)dataDir.VirtualAddress); - writer.WriteUInt32(dataDir.Size); - } - - static void WriteByte(DataWriter writer, byte? value) { - if (value is null) - writer.Position++; - else - writer.WriteByte(value.Value); - } - - static void WriteUInt16(DataWriter writer, ushort? value) { - if (value is null) - writer.Position += 2; - else - writer.WriteUInt16(value.Value); - } - - static void WriteUInt16(DataWriter writer, Subsystem? value) { - if (value is null) - writer.Position += 2; - else - writer.WriteUInt16((ushort)value.Value); - } - - static void WriteUInt16(DataWriter writer, DllCharacteristics? value) { - if (value is null) - writer.Position += 2; - else - writer.WriteUInt16((ushort)value.Value); - } - - static void WriteUInt32(DataWriter writer, uint? value) { - if (value is null) - writer.Position += 4; - else - writer.WriteUInt32(value.Value); - } - - static void WriteUInt32(DataWriter writer, ulong? value) { - if (value is null) - writer.Position += 4; - else - writer.WriteUInt32((uint)value.Value); - } - - static void WriteUInt64(DataWriter writer, ulong? value) { - if (value is null) - writer.Position += 8; - else - writer.WriteUInt64(value.Value); - } - - ComImageFlags GetComImageFlags(bool isManagedEntryPoint) { - var flags = Options.Cor20HeaderOptions.Flags ?? module.Cor20HeaderFlags; - if (Options.Cor20HeaderOptions.EntryPoint is not null) - return flags; - if (isManagedEntryPoint) - return flags & ~ComImageFlags.NativeEntryPoint; - return flags | ComImageFlags.NativeEntryPoint; - } - - Subsystem GetSubsystem() { - if (module.Kind == ModuleKind.Windows) - return Subsystem.WindowsGui; - return Subsystem.WindowsCui; - } - - /// - /// Converts to a file offset in the destination stream - /// - /// RVA - long ToWriterOffset(RVA rva) { - if (rva == 0) - return 0; - foreach (var sect in origSections) { - var section = sect.PESection; - if (section.VirtualAddress <= rva && rva < section.VirtualAddress + Math.Max(section.VirtualSize, section.SizeOfRawData)) - return destStreamBaseOffset + (long)sect.Chunk.FileOffset + (rva - section.VirtualAddress); - } - return 0; - } - - IEnumerable GetSectionSizeInfos() { - foreach (var section in origSections) - yield return new SectionSizeInfo(section.Chunk.GetVirtualSize(), section.PESection.Characteristics); - foreach (var section in sections) - yield return new SectionSizeInfo(section.GetVirtualSize(), section.Characteristics); - } - - void UpdateVTableFixups(DataWriter writer) { - var vtableFixups = module.VTableFixups; - if (vtableFixups is null || vtableFixups.VTables.Count == 0) - return; - - writer.Position = ToWriterOffset(vtableFixups.RVA); - if (writer.Position == 0) { - Error("Could not convert RVA to file offset"); - return; - } - foreach (var vtable in vtableFixups) { - if (vtable.Methods.Count > ushort.MaxValue) - throw new ModuleWriterException("Too many methods in vtable"); - 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); - if (writer.Position == 0) { - if (vtable.RVA != 0 || vtable.Methods.Count > 0) - Error("Could not convert RVA to file offset"); - } - else { - 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); - } - } - writer.Position = pos; - } - } - - uint GetMethodToken(IMethod method) { - if (method is MethodDef md) - return new MDToken(Table.Method, metadata.GetRid(md)).Raw; - - if (method is MemberRef mr) - return new MDToken(Table.MemberRef, metadata.GetRid(mr)).Raw; - - if (method is MethodSpec ms) - return new MDToken(Table.MethodSpec, metadata.GetRid(ms)).Raw; - - if (method is null) - return 0; - - Error("Invalid VTable method type: {0}", method.GetType()); - return 0; - } - - /// - /// Gets the entry point - /// - /// Updated with entry point (either a token or RVA of native 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 is not null) { - ep = tok.Value; - return ep == 0 || ((Options.Cor20HeaderOptions.Flags ?? 0) & ComImageFlags.NativeEntryPoint) == 0; - } - - if (module.ManagedEntryPoint is MethodDef epMethod) { - ep = new MDToken(Table.Method, metadata.GetRid(epMethod)).Raw; - return true; - } - if (module.ManagedEntryPoint is FileDef file) { - ep = new MDToken(Table.File, metadata.GetRid(file)).Raw; - return true; - } - ep = (uint)module.NativeEntryPoint; - return ep == 0; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/NetResources.cs b/Plugins/dnlib/DotNet/Writer/NetResources.cs deleted file mode 100644 index f2986f2..0000000 --- a/Plugins/dnlib/DotNet/Writer/NetResources.cs +++ /dev/null @@ -1,93 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// .NET resources - /// - public sealed class NetResources : IReuseChunk { - readonly List resources = new List(); - readonly uint alignment; - uint length; - bool setOffsetCalled; - FileOffset offset; - RVA rva; - - internal bool IsEmpty => resources.Count == 0; - - /// - public FileOffset FileOffset => offset; - - /// - 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 => Utils.AlignUp(length, alignment); - - /// - /// Constructor - /// - /// Alignment of all resources - public NetResources(uint alignment) => this.alignment = alignment; - - /// - /// Adds a resource - /// - /// The resource data - /// The resource data - public DataReaderChunk Add(DataReader reader) { - if (setOffsetCalled) - throw new InvalidOperationException("SetOffset() has already been called"); - length = NextOffset + 4 + reader.Length; - var data = new DataReaderChunk(ref reader); - resources.Add(data); - return data; - } - - bool IReuseChunk.CanReuse(RVA origRva, 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 += len; - rva += len; - } - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - var rva2 = rva; - foreach (var resourceData in resources) { - int padding = (int)rva2.AlignUp(alignment) - (int)rva2; - writer.WriteZeroes(padding); - rva2 += (uint)padding; - writer.WriteUInt32(resourceData.GetFileLength()); - resourceData.VerifyWriteTo(writer); - rva2 += 4 + resourceData.GetFileLength(); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/NormalMetadata.cs b/Plugins/dnlib/DotNet/Writer/NormalMetadata.cs deleted file mode 100644 index 1e8443c..0000000 --- a/Plugins/dnlib/DotNet/Writer/NormalMetadata.cs +++ /dev/null @@ -1,329 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Linq; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Writer { - /// - /// Does not preserve metadata tokens - /// - sealed class NormalMetadata : Metadata { - readonly Rows typeRefInfos = new Rows(); - readonly Rows typeDefInfos = new Rows(); - readonly Rows fieldDefInfos = new Rows(); - readonly Rows methodDefInfos = new Rows(); - readonly Rows paramDefInfos = new Rows(); - readonly Rows memberRefInfos = new Rows(); - readonly Rows standAloneSigInfos = new Rows(); - readonly Rows eventDefInfos = new Rows(); - readonly Rows propertyDefInfos = new Rows(); - readonly Rows typeSpecInfos = new Rows(); - readonly Rows methodSpecInfos = new Rows(); - - 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) { - } - - /// - protected override TypeDef[] GetAllTypeDefs() { - // All nested types must be after their enclosing type. This is exactly - // what module.GetTypes() does. - return module.GetTypes().ToArray(); - } - - /// - protected override void AllocateTypeDefRids() { - foreach (var type in allTypeDefs) { - if (type is null) - continue; - uint rid = tablesHeap.TypeDefTable.Create(new RawTypeDefRow()); - typeDefInfos.Add(type, rid); - } - } - - /// - protected override void AllocateMemberDefRids() { - int numTypes = allTypeDefs.Length; - int typeNum = 0; - int notifyNum = 0; - const int numNotifyEvents = 5; - int notifyAfter = numTypes / numNotifyEvents; - - 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); - notifyNum++; - notifyAfter = (int)((double)numTypes / numNotifyEvents * (notifyNum + 1)); - } - - if (type is null) - continue; - uint typeRid = GetRid(type); - var typeRow = tablesHeap.TypeDefTable[typeRid]; - typeRow = new RawTypeDefRow(typeRow.Flags, typeRow.Name, typeRow.Namespace, typeRow.Extends, fieldListRid, methodListRid); - tablesHeap.TypeDefTable[typeRid] = typeRow; - - var fields = type.Fields; - count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (field is null) - continue; - uint rid = fieldListRid++; - if (rid != tablesHeap.FieldTable.Create(new RawFieldRow())) - throw new ModuleWriterException("Invalid field rid"); - fieldDefInfos.Add(field, rid); - } - - var methods = type.Methods; - count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method is null) - continue; - uint rid = methodListRid++; - var row = new RawMethodRow(0, 0, 0, 0, 0, paramListRid); - if (rid != tablesHeap.MethodTable.Create(row)) - throw new ModuleWriterException("Invalid method rid"); - methodDefInfos.Add(method, rid); - foreach (var pd in Sort(method.ParamDefs)) { - if (pd is null) - continue; - uint pdRid = paramListRid++; - if (pdRid != tablesHeap.ParamTable.Create(new RawParamRow())) - throw new ModuleWriterException("Invalid param rid"); - paramDefInfos.Add(pd, pdRid); - } - } - - if (!IsEmpty(type.Events)) { - uint eventMapRid = tablesHeap.EventMapTable.Create(new RawEventMapRow(typeRid, eventListRid)); - eventMapInfos.Add(type, eventMapRid); - var events = type.Events; - count = events.Count; - for (int i = 0; i < count; i++) { - var evt = events[i]; - if (evt is null) - continue; - uint rid = eventListRid++; - if (rid != tablesHeap.EventTable.Create(new RawEventRow())) - throw new ModuleWriterException("Invalid event rid"); - eventDefInfos.Add(evt, rid); - } - } - - if (!IsEmpty(type.Properties)) { - uint propertyMapRid = tablesHeap.PropertyMapTable.Create(new RawPropertyMapRow(typeRid, propertyListRid)); - propertyMapInfos.Add(type, propertyMapRid); - var properties = type.Properties; - count = properties.Count; - for (int i = 0; i < count; i++) { - var prop = properties[i]; - if (prop is null) - continue; - uint rid = propertyListRid++; - if (rid != tablesHeap.PropertyTable.Create(new RawPropertyRow())) - throw new ModuleWriterException("Invalid property rid"); - propertyDefInfos.Add(prop, rid); - } - } - } - } - - /// - public override uint GetRid(TypeRef tr) { - typeRefInfos.TryGetRid(tr, out uint rid); - return rid; - } - - /// - public override uint GetRid(TypeDef td) { - if (typeDefInfos.TryGetRid(td, out uint rid)) - return rid; - if (td is null) - Error("TypeDef is null"); - else - 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; - } - - /// - public override uint GetRid(FieldDef fd) { - if (fieldDefInfos.TryGetRid(fd, out uint rid)) - return rid; - if (fd is null) - Error("Field is null"); - else - 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; - } - - /// - public override uint GetRid(MethodDef md) { - if (methodDefInfos.TryGetRid(md, out uint rid)) - return rid; - if (md is null) - Error("Method is null"); - else - 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; - } - - /// - public override uint GetRid(ParamDef pd) { - if (paramDefInfos.TryGetRid(pd, out uint rid)) - return rid; - if (pd is null) - Error("Param is null"); - else - 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; - } - - /// - public override uint GetRid(MemberRef mr) { - memberRefInfos.TryGetRid(mr, out uint rid); - return rid; - } - - /// - public override uint GetRid(StandAloneSig sas) { - standAloneSigInfos.TryGetRid(sas, out uint rid); - return rid; - } - - /// - public override uint GetRid(EventDef ed) { - if (eventDefInfos.TryGetRid(ed, out uint rid)) - return rid; - if (ed is null) - Error("Event is null"); - else - 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; - } - - /// - public override uint GetRid(PropertyDef pd) { - if (propertyDefInfos.TryGetRid(pd, out uint rid)) - return rid; - if (pd is null) - Error("Property is null"); - else - 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; - } - - /// - public override uint GetRid(TypeSpec ts) { - typeSpecInfos.TryGetRid(ts, out uint rid); - return rid; - } - - /// - public override uint GetRid(MethodSpec ms) { - methodSpecInfos.TryGetRid(ms, out uint rid); - return rid; - } - - /// - protected override uint AddTypeRef(TypeRef tr) { - if (tr is null) { - Error("TypeRef is null"); - return 0; - } - if (typeRefInfos.TryGetRid(tr, out uint rid)) { - if (rid == 0) - Error("TypeRef 0x{0:X8} has an infinite ResolutionScope loop.", tr.MDToken.Raw); - return rid; - } - typeRefInfos.Add(tr, 0); // Prevent inf recursion - var row = new RawTypeRefRow(AddResolutionScope(tr.ResolutionScope), - stringsHeap.Add(tr.Name), - stringsHeap.Add(tr.Namespace)); - rid = tablesHeap.TypeRefTable.Add(row); - typeRefInfos.SetRid(tr, rid); - AddCustomAttributes(Table.TypeRef, rid, tr); - AddCustomDebugInformationList(Table.TypeRef, rid, tr); - return rid; - } - - /// - protected override uint AddTypeSpec(TypeSpec ts) { - if (ts is null) { - Error("TypeSpec is null"); - return 0; - } - if (typeSpecInfos.TryGetRid(ts, out uint rid)) { - if (rid == 0) - Error("TypeSpec 0x{0:X8} has an infinite TypeSig loop.", ts.MDToken.Raw); - return rid; - } - typeSpecInfos.Add(ts, 0); // Prevent inf recursion - var row = new RawTypeSpecRow(GetSignature(ts.TypeSig, ts.ExtraData)); - rid = tablesHeap.TypeSpecTable.Add(row); - typeSpecInfos.SetRid(ts, rid); - AddCustomAttributes(Table.TypeSpec, rid, ts); - AddCustomDebugInformationList(Table.TypeSpec, rid, ts); - return rid; - } - - /// - protected override uint AddMemberRef(MemberRef mr) { - if (mr is null) { - Error("MemberRef is null"); - return 0; - } - - if (memberRefInfos.TryGetRid(mr, out uint rid)) - return rid; - var row = new RawMemberRefRow(AddMemberRefParent(mr.Class), - stringsHeap.Add(mr.Name), - GetSignature(mr.Signature)); - rid = tablesHeap.MemberRefTable.Add(row); - memberRefInfos.Add(mr, rid); - AddCustomAttributes(Table.MemberRef, rid, mr); - AddCustomDebugInformationList(Table.MemberRef, rid, mr); - return rid; - } - - /// - protected override uint AddStandAloneSig(StandAloneSig sas) { - if (sas is null) { - Error("StandAloneSig is null"); - return 0; - } - if (standAloneSigInfos.TryGetRid(sas, out uint rid)) - return rid; - var row = new RawStandAloneSigRow(GetSignature(sas.Signature)); - rid = tablesHeap.StandAloneSigTable.Add(row); - standAloneSigInfos.Add(sas, rid); - AddCustomAttributes(Table.StandAloneSig, rid, sas); - AddCustomDebugInformationList(Table.StandAloneSig, rid, sas); - return rid; - } - - /// - protected override uint AddMethodSpec(MethodSpec ms) { - if (ms is null) { - Error("MethodSpec is null"); - return 0; - } - if (methodSpecInfos.TryGetRid(ms, out uint rid)) - return rid; - var row = new RawMethodSpecRow(AddMethodDefOrRef(ms.Method), - GetSignature(ms.Instantiation)); - rid = tablesHeap.MethodSpecTable.Add(row); - methodSpecInfos.Add(ms, rid); - AddCustomAttributes(Table.MethodSpec, rid, ms); - AddCustomDebugInformationList(Table.MethodSpec, rid, ms); - return rid; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/PEHeaders.cs b/Plugins/dnlib/DotNet/Writer/PEHeaders.cs deleted file mode 100644 index 34502b7..0000000 --- a/Plugins/dnlib/DotNet/Writer/PEHeaders.cs +++ /dev/null @@ -1,490 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// options - /// - public sealed class PEHeadersOptions { - /// - /// Default DLL characteristics - /// - public const DllCharacteristics DefaultDllCharacteristics = dnlib.PE.DllCharacteristics.TerminalServerAware | dnlib.PE.DllCharacteristics.NoSeh | dnlib.PE.DllCharacteristics.NxCompat | dnlib.PE.DllCharacteristics.DynamicBase; - - /// - /// Default subsystem value - /// - public const Subsystem DEFAULT_SUBSYSTEM = dnlib.PE.Subsystem.WindowsGui; - - /// - /// Default major linker version. Roslyn C# defaults to 0x30, and Roslyn VB defaults to 0x50. - /// - public const byte DEFAULT_MAJOR_LINKER_VERSION = 11; - - /// - /// Default minor linker version - /// - public const byte DEFAULT_MINOR_LINKER_VERSION = 0; - - /// - /// IMAGE_FILE_HEADER.Machine value - /// - public Machine? Machine; - - /// - /// IMAGE_FILE_HEADER.TimeDateStamp value - /// - public uint? TimeDateStamp; - - /// - /// IMAGE_FILE_HEADER.PointerToSymbolTable value - /// - public uint? PointerToSymbolTable; - - /// - /// IMAGE_FILE_HEADER.NumberOfSymbols value - /// - public uint? NumberOfSymbols; - - /// - /// IMAGE_FILE_HEADER.Characteristics value. bit - /// is ignored and set/cleared depending on whether it's a EXE or a DLL file. - /// - public Characteristics? Characteristics; - - /// - /// IMAGE_OPTIONAL_HEADER.MajorLinkerVersion value - /// - public byte? MajorLinkerVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MinorLinkerVersion value - /// - public byte? MinorLinkerVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.ImageBase value - /// - public ulong? ImageBase; - - /// - /// IMAGE_OPTIONAL_HEADER.SectionAlignment value - /// - public uint? SectionAlignment; - - /// - /// IMAGE_OPTIONAL_HEADER.FileAlignment value - /// - public uint? FileAlignment; - - /// - /// IMAGE_OPTIONAL_HEADER.MajorOperatingSystemVersion value - /// - public ushort? MajorOperatingSystemVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MinorOperatingSystemVersion value - /// - public ushort? MinorOperatingSystemVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MajorImageVersion value - /// - public ushort? MajorImageVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MinorImageVersion value - /// - public ushort? MinorImageVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion value - /// - public ushort? MajorSubsystemVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.MinorSubsystemVersion value - /// - public ushort? MinorSubsystemVersion; - - /// - /// IMAGE_OPTIONAL_HEADER.Win32VersionValue value - /// - public uint? Win32VersionValue; - - /// - /// IMAGE_OPTIONAL_HEADER.Subsystem value - /// - public Subsystem? Subsystem; - - /// - /// IMAGE_OPTIONAL_HEADER.DllCharacteristics value - /// - public DllCharacteristics? DllCharacteristics; - - /// - /// IMAGE_OPTIONAL_HEADER.SizeOfStackReserve value - /// - public ulong? SizeOfStackReserve; - - /// - /// IMAGE_OPTIONAL_HEADER.SizeOfStackCommit value - /// - public ulong? SizeOfStackCommit; - - /// - /// IMAGE_OPTIONAL_HEADER.SizeOfHeapReserve value - /// - public ulong? SizeOfHeapReserve; - - /// - /// IMAGE_OPTIONAL_HEADER.SizeOfHeapCommit value - /// - public ulong? SizeOfHeapCommit; - - /// - /// IMAGE_OPTIONAL_HEADER.LoaderFlags value - /// - public uint? LoaderFlags; - - /// - /// IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes value - /// - public uint? NumberOfRvaAndSizes; - - /// - /// Creates a new time date stamp using current time - /// - /// A new time date stamp - public static uint CreateNewTimeDateStamp() => (uint)(DateTime.UtcNow - Epoch).TotalSeconds; - static readonly DateTime Epoch = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc); - } - - /// - /// DOS and PE headers - /// - public sealed class PEHeaders : IChunk { - IList sections; - readonly PEHeadersOptions options; - FileOffset offset; - RVA rva; - uint length; - readonly uint sectionAlignment; - readonly uint fileAlignment; - ulong imageBase; - long startOffset; - long checkSumOffset; - bool isExeFile; - - // Copied from Partition II.25.2.1 - static readonly byte[] dosHeader = new byte[0x80] { - 0x4D, 0x5A, 0x90, 0x00, 0x03, 0x00, 0x00, 0x00, - 0x04, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00, - 0xB8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, - 0x0E, 0x1F, 0xBA, 0x0E, 0x00, 0xB4, 0x09, 0xCD, - 0x21, 0xB8, 0x01, 0x4C, 0xCD, 0x21, 0x54, 0x68, - 0x69, 0x73, 0x20, 0x70, 0x72, 0x6F, 0x67, 0x72, - 0x61, 0x6D, 0x20, 0x63, 0x61, 0x6E, 0x6E, 0x6F, - 0x74, 0x20, 0x62, 0x65, 0x20, 0x72, 0x75, 0x6E, - 0x20, 0x69, 0x6E, 0x20, 0x44, 0x4F, 0x53, 0x20, - 0x6D, 0x6F, 0x64, 0x65, 0x2E, 0x0D, 0x0D, 0x0A, - 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - }; - - /// - /// Gets/sets the native entry point - /// - public StartupStub StartupStub { get; set; } - - /// - /// Gets/sets the COR20 header - /// - public ImageCor20Header ImageCor20Header { get; set; } - - /// - /// Gets/sets the IAT - /// - public ImportAddressTable ImportAddressTable { get; set; } - - /// - /// Gets/sets the - /// - public ImportDirectory ImportDirectory { get; set; } - - /// - /// Gets/sets the Win32 resources - /// - public Win32ResourcesChunk Win32Resources { get; set; } - - /// - /// Gets/sets the relocation directory - /// - public RelocDirectory RelocDirectory { get; set; } - - /// - /// Gets/sets the debug directory - /// - public DebugDirectory DebugDirectory { get; set; } - - internal IChunk ExportDirectory { get; set; } - - /// - /// Gets the image base - /// - public ulong ImageBase => imageBase; - - /// - /// Gets/sets a value indicating whether this is a EXE or a DLL file - /// - public bool IsExeFile { - get => isExeFile; - set => isExeFile = value; - } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets the section alignment - /// - public uint SectionAlignment => sectionAlignment; - - /// - /// Gets the file alignment - /// - public uint FileAlignment => fileAlignment; - - /// - /// Gets/sets the s - /// - public IList PESections { - get => sections; - set => sections = value; - } - - /// - /// Default constructor - /// - public PEHeaders() - : this(new PEHeadersOptions()) { - } - - /// - /// Constructor - /// - /// Options - public PEHeaders(PEHeadersOptions options) { - this.options = options ?? new PEHeadersOptions(); - sectionAlignment = this.options.SectionAlignment ?? 0x2000; - fileAlignment = this.options.FileAlignment ?? 0x200; - } - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - - length = (uint)dosHeader.Length; - length += 4 + 0x14; - length += Use32BitOptionalHeader() ? 0xE0U : 0xF0; - length += (uint)sections.Count * 0x28; - - if (Use32BitOptionalHeader()) - imageBase = options.ImageBase ?? (IsExeFile ? 0x00400000UL : 0x10000000); - else - imageBase = options.ImageBase ?? (IsExeFile ? 0x0000000140000000UL : 0x0000000180000000); - } - - int SectionsCount { - get { - int count = 0; - foreach (var section in sections) { - if (section.GetVirtualSize() != 0) - count++; - } - return count; - } - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - IEnumerable GetSectionSizeInfos() { - foreach (var section in sections) { - uint virtSize = section.GetVirtualSize(); - if (virtSize != 0) - yield return new SectionSizeInfo(virtSize, section.Characteristics); - } - } - - /// - public void WriteTo(DataWriter writer) { - startOffset = writer.Position; - - // DOS header - writer.WriteBytes(dosHeader); - - // PE magic - writer.WriteInt32(0x00004550); - - // Image file header - 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.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 is null || !StartupStub.Enable ? 0 : (uint)StartupStub.EntryPointRVA; - if (Use32BitOptionalHeader()) { - 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.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.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.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); - writer.WriteDataDirectory(ImportDirectory); - writer.WriteDataDirectory(Win32Resources); - writer.WriteDataDirectory(null); // Exception table - writer.WriteDataDirectory(null); // Certificate table - writer.WriteDataDirectory(RelocDirectory); - writer.WriteDebugDirectory(DebugDirectory); - writer.WriteDataDirectory(null); // Architecture-specific data - writer.WriteDataDirectory(null); // Global pointer register RVA - writer.WriteDataDirectory(null); // Thread local storage - writer.WriteDataDirectory(null); // Load configuration table - writer.WriteDataDirectory(null); // Bound import table - writer.WriteDataDirectory(ImportAddressTable); - writer.WriteDataDirectory(null); // Delay import descriptor - writer.WriteDataDirectory(ImageCor20Header); - writer.WriteDataDirectory(null); // Reserved - - // Sections - uint rva = Utils.AlignUp(sectionSizes.SizeOfHeaders, sectionAlignment); - 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.Position += emptySections * 0x28; - } - - /// - /// Calculates the PE checksum and writes it to the checksum field - /// - /// Writer - /// Length of PE file - public void WriteCheckSum(DataWriter writer, long length) { - writer.Position = startOffset; - uint checkSum = writer.InternalStream.CalculatePECheckSum(length, checkSumOffset); - writer.Position = checkSumOffset; - writer.WriteUInt32(checkSum); - } - - Machine GetMachine() => options.Machine ?? Machine.I386; - - bool Use32BitOptionalHeader() => !GetMachine().Is64Bit(); - - Characteristics GetCharacteristics() { - var chr = options.Characteristics ?? GetDefaultCharacteristics(); - if (IsExeFile) - chr &= ~Characteristics.Dll; - else - chr |= Characteristics.Dll; - return chr; - } - - Characteristics GetDefaultCharacteristics() { - if (Use32BitOptionalHeader()) - return Characteristics.Bit32Machine | Characteristics.ExecutableImage; - return Characteristics.ExecutableImage | Characteristics.LargeAddressAware; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/PESection.cs b/Plugins/dnlib/DotNet/Writer/PESection.cs deleted file mode 100644 index df7a44c..0000000 --- a/Plugins/dnlib/DotNet/Writer/PESection.cs +++ /dev/null @@ -1,84 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Text; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// A PE section - /// - public sealed class PESection : ChunkList { - string name; - uint characteristics; - - /// - /// Gets the name - /// - public string Name { - get => name; - set => name = value; - } - - /// - /// Gets the Characteristics - /// - public uint Characteristics { - get => characteristics; - set => characteristics = value; - } - - /// - /// true if this is a code section - /// - public bool IsCode => (characteristics & 0x20) != 0; - - /// - /// true if this is an initialized data section - /// - public bool IsInitializedData => (characteristics & 0x40) != 0; - - /// - /// true if this is an uninitialized data section - /// - public bool IsUninitializedData => (characteristics & 0x80) != 0; - - /// - /// Constructor - /// - /// Section name - /// Section characteristics - public PESection(string name, uint characteristics) { - this.name = name; - this.characteristics = characteristics; - } - - /// - /// Writes the section header to at its current position. - /// Returns aligned virtual size (aligned to ) - /// - /// Writer - /// File alignment - /// Section alignment - /// Current - public uint WriteHeaderTo(DataWriter writer, uint fileAlignment, uint sectionAlignment, uint rva) { - uint vs = GetVirtualSize(); - uint fileLen = GetFileLength(); - uint alignedVs = Utils.AlignUp(vs, sectionAlignment); - uint rawSize = Utils.AlignUp(fileLen, fileAlignment); - uint dataOffset = (uint)FileOffset; - - writer.WriteBytes(Encoding.UTF8.GetBytes(Name + "\0\0\0\0\0\0\0\0"), 0, 8); - writer.WriteUInt32(vs); // VirtualSize - writer.WriteUInt32(rva); // VirtualAddress - writer.WriteUInt32(rawSize); // SizeOfRawData - writer.WriteUInt32(dataOffset); // PointerToRawData - writer.WriteInt32(0); // PointerToRelocations - writer.WriteInt32(0); // PointerToLinenumbers - writer.WriteUInt16(0); // NumberOfRelocations - writer.WriteUInt16(0); // NumberOfLinenumbers - writer.WriteUInt32(Characteristics); - - return alignedVs; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/PdbHeap.cs b/Plugins/dnlib/DotNet/Writer/PdbHeap.cs deleted file mode 100644 index 0dadf73..0000000 --- a/Plugins/dnlib/DotNet/Writer/PdbHeap.cs +++ /dev/null @@ -1,100 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; -using dnlib.Protection; - -namespace dnlib.DotNet.Writer { - /// - /// #Pdb heap - /// - public sealed class PdbHeap : HeapBase { - /// - public override string Name => "#Pdb"; - - /// - /// Gets the PDB ID. This is always 20 bytes in size. - /// - public byte[] PdbId => pdbId; - readonly byte[] pdbId; - - /// - /// Gets/sets the entry point token - /// - public uint EntryPoint { - get => entryPoint; - set => entryPoint = value; - } - uint entryPoint; - - /// - /// Gets the offset of the 20-byte PDB ID - /// - public FileOffset PdbIdOffset => FileOffset; - - /// - /// 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 => 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 EncryptionMethod GetEncryptionMethod(IEncryption e) => null; - - /// - protected override void WriteToImpl(DataWriter writer) { - if (!referencedTypeSystemTablesInitd) - throw new InvalidOperationException("ReferencedTypeSystemTables hasn't been initialized yet"); - 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.WriteUInt32(typeSystemTableRows[i]); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/PortablePdbConstants.cs b/Plugins/dnlib/DotNet/Writer/PortablePdbConstants.cs deleted file mode 100644 index 3bd5f14..0000000 --- a/Plugins/dnlib/DotNet/Writer/PortablePdbConstants.cs +++ /dev/null @@ -1,21 +0,0 @@ -// 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 FormatVersion = 0x0100; - - // Embedded Portable PDB Blob verison (v1.0) - // Embedded version is stored in DebugDirectory.MinorVersion - // SRM: MinEmbeddedVersion, DefaultEmbeddedVersion, MinUnsupportedEmbeddedVersion - public const ushort 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/Plugins/dnlib/DotNet/Writer/PreserveTokensMetadata.cs b/Plugins/dnlib/DotNet/Writer/PreserveTokensMetadata.cs deleted file mode 100644 index 376adaf..0000000 --- a/Plugins/dnlib/DotNet/Writer/PreserveTokensMetadata.cs +++ /dev/null @@ -1,1232 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using dnlib.DotNet.MD; - -namespace dnlib.DotNet.Writer { - /// - /// Preserves metadata tokens - /// - sealed class PreserveTokensMetadata : Metadata { - readonly ModuleDefMD mod; - readonly Rows typeRefInfos = new Rows(); - readonly Dictionary typeToRid = new Dictionary(); - MemberDefDict fieldDefInfos; - MemberDefDict methodDefInfos; - MemberDefDict paramDefInfos; - readonly Rows memberRefInfos = new Rows(); - readonly Rows standAloneSigInfos = new Rows(); - MemberDefDict eventDefInfos; - MemberDefDict propertyDefInfos; - readonly Rows typeSpecInfos = new Rows(); - readonly Rows methodSpecInfos = new Rows(); - readonly Dictionary callConvTokenToSignature = new Dictionary(); - - [DebuggerDisplay("{Rid} -> {NewRid} {Def}")] - sealed class MemberDefInfo where T : IMDTokenProvider { - public readonly T Def; - - /// - /// Its real rid - /// - public uint Rid; - - /// - /// Its logical rid or real rid. If the ptr table exists (eg. MethodPtr), then it's - /// an index into it, else it's the real rid. - /// - public uint NewRid; - - public MemberDefInfo(T def, uint rid) { - Def = def; - Rid = rid; - NewRid = rid; - } - } - - [DebuggerDisplay("Count = {Count}")] - sealed class MemberDefDict where T : IMDTokenProvider { - readonly Type defMDType; - uint userRid = 0x01000000; - uint newRid = 1; - int numDefMDs; - int numDefUsers; - int tableSize; - bool wasSorted; - readonly bool preserveRids; - readonly bool enableRidToInfo; - readonly Dictionary> defToInfo = new Dictionary>(); - Dictionary> ridToInfo; - readonly List> defs = new List>(); - List> sortedDefs; - readonly Dictionary collectionPositions = new Dictionary(); - - /// - /// Gets total number of defs in the list. It does not necessarily return - /// the table size. Use for that. - /// - public int Count => defs.Count; - - /// - /// Gets the number of rows that need to be created in the table - /// - public int TableSize => tableSize; - - /// - /// Returns true if the ptr table (eg. MethodPtr) is needed - /// - public bool NeedPtrTable => preserveRids && !wasSorted; - - public MemberDefDict(Type defMDType, bool preserveRids) - : this(defMDType, preserveRids, false) { - } - - public MemberDefDict(Type defMDType, bool preserveRids, bool enableRidToInfo) { - this.defMDType = defMDType; - this.preserveRids = preserveRids; - this.enableRidToInfo = enableRidToInfo; - } - - public uint Rid(T def) => defToInfo[def].Rid; - - public bool TryGetRid(T def, out uint rid) { - if (def == null || !defToInfo.TryGetValue(def, out var info)) { - rid = 0; - return false; - } - rid = info.Rid; - return true; - } - - /// - /// Sorts the table - /// - /// Comparer - public void Sort(Comparison> comparer) { - if (!preserveRids) { - // It's already sorted - sortedDefs = defs; - return; - } - - sortedDefs = new List>(defs); - sortedDefs.Sort(comparer); - wasSorted = true; - for (int i = 0; i < sortedDefs.Count; i++) { - var def = sortedDefs[i]; - uint newRid = (uint)i + 1; - def.NewRid = newRid; - if (def.Rid != newRid) - wasSorted = false; - } - } - - public MemberDefInfo Get(int i) => defs[i]; - public MemberDefInfo GetSorted(int i) => sortedDefs[i]; - - public MemberDefInfo GetByRid(uint rid) { - ridToInfo.TryGetValue(rid, out var info); - return info; - } - - /// - /// Adds a def. must be called after adding the last def. - /// - /// The def - /// Collection position - public void Add(T def, int collPos) { - uint rid; - if (def.GetType() == defMDType) { - numDefMDs++; - rid = preserveRids ? def.Rid : newRid++; - } - else { - numDefUsers++; - rid = preserveRids ? userRid++ : newRid++; - } - - var info = new MemberDefInfo(def, rid); - defToInfo[def] = info; - defs.Add(info); - collectionPositions.Add(def, collPos); - } - - /// - /// Must be called after 'ing the last def - /// - public void SortDefs() { - // It's already sorted if we don't preserve rids - if (preserveRids) { - // Sort all def MDs before user defs - defs.Sort((a, b) => a.Rid.CompareTo(b.Rid)); - - // Fix user created defs' rids - uint newRid = numDefMDs == 0 ? 1 : defs[numDefMDs - 1].Rid + 1; - for (int i = numDefMDs; i < defs.Count; i++) - defs[i].Rid = newRid++; - - // Now we know total table size - tableSize = (int)newRid - 1; - } - else - tableSize = defs.Count; - - if (enableRidToInfo) { - ridToInfo = new Dictionary>(defs.Count); - foreach (var info in defs) - ridToInfo.Add(info.Rid, info); - } - - if ((uint)tableSize > 0x00FFFFFF) - throw new ModuleWriterException("Table is too big"); - } - - public int GetCollectionPosition(T def) => collectionPositions[def]; - } - - 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) { - mod = module as ModuleDefMD; - if (mod is null) - throw new ModuleWriterException("Not a ModuleDefMD"); - } - - /// - public override uint GetRid(TypeRef tr) { - typeRefInfos.TryGetRid(tr, out uint rid); - return rid; - } - - /// - public override uint GetRid(TypeDef td) { - if (td is null) { - Error("TypeDef is null"); - return 0; - } - if (typeToRid.TryGetValue(td, out uint rid)) - return rid; - 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; - } - - /// - public override uint GetRid(FieldDef fd) { - if (fieldDefInfos.TryGetRid(fd, out uint rid)) - return rid; - if (fd is null) - Error("Field is null"); - else - 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; - } - - /// - public override uint GetRid(MethodDef md) { - if (methodDefInfos.TryGetRid(md, out uint rid)) - return rid; - if (md is null) - Error("Method is null"); - else - 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; - } - - /// - public override uint GetRid(ParamDef pd) { - if (paramDefInfos.TryGetRid(pd, out uint rid)) - return rid; - if (pd is null) - Error("Param is null"); - else - 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; - } - - /// - public override uint GetRid(MemberRef mr) { - memberRefInfos.TryGetRid(mr, out uint rid); - return rid; - } - - /// - public override uint GetRid(StandAloneSig sas) { - standAloneSigInfos.TryGetRid(sas, out uint rid); - return rid; - } - - /// - public override uint GetRid(EventDef ed) { - if (eventDefInfos.TryGetRid(ed, out uint rid)) - return rid; - if (ed is null) - Error("Event is null"); - else - 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; - } - - /// - public override uint GetRid(PropertyDef pd) { - if (propertyDefInfos.TryGetRid(pd, out uint rid)) - return rid; - if (pd is null) - Error("Property is null"); - else - 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; - } - - /// - public override uint GetRid(TypeSpec ts) { - typeSpecInfos.TryGetRid(ts, out uint rid); - return rid; - } - - /// - public override uint GetRid(MethodSpec ms) { - methodSpecInfos.TryGetRid(ms, out uint rid); - return rid; - } - - /// - protected override void Initialize() { - fieldDefInfos = new MemberDefDict(typeof(FieldDefMD), PreserveFieldRids); - methodDefInfos = new MemberDefDict(typeof(MethodDefMD), PreserveMethodRids, true); - paramDefInfos = new MemberDefDict(typeof(ParamDefMD), PreserveParamRids); - eventDefInfos = new MemberDefDict(typeof(EventDefMD), PreserveEventRids); - propertyDefInfos = new MemberDefDict(typeof(PropertyDefMD), PreservePropertyRids); - - CreateEmptyTableRows(); - } - - /// - protected override TypeDef[] GetAllTypeDefs() { - if (!PreserveTypeDefRids) { - var types2 = module.GetTypes().ToArray(); - InitializeTypeToRid(types2); - return types2; - } - - var typeToIndex = new Dictionary(); - var types = new List(); - uint index = 0; - const uint IS_TYPEDEFMD = 0x80000000; - const uint INDEX_BITS = 0x00FFFFFF; - foreach (var type in module.GetTypes()) { - if (type is null) - continue; - types.Add(type); - uint val = (uint)index++; - if (type.GetType() == typeof(TypeDefMD)) - val |= IS_TYPEDEFMD; - typeToIndex[type] = val; - } - - var globalType = types[0]; - types.Sort((a, b) => { - if (a == b) - return 0; - // Make sure the global type is always sorted first, even if it's - // a TypeDefUser - if (a == globalType) - return -1; - if (b == globalType) - return 1; - - // Sort all TypeDefMDs before all TypeDefUsers - uint ai = typeToIndex[a]; - uint bi = typeToIndex[b]; - bool amd = (ai & IS_TYPEDEFMD) != 0; - bool bmd = (bi & IS_TYPEDEFMD) != 0; - if (amd == bmd) { // Both are TypeDefMDs or both are TypeDefUsers - // If TypeDefMDs, only compare rids since rids are preserved - if (amd) - return a.Rid.CompareTo(b.Rid); - - // If TypeDefUsers, rids aren't preserved so compare by index - return (ai & INDEX_BITS).CompareTo(bi & INDEX_BITS); - } - if (amd) - return -1; - return 1; - }); - - // Some of the original types may have been removed. Create dummy types - // so TypeDef rids can be preserved. - var newTypes = new List(types.Count); - uint prevRid = 1; - newTypes.Add(globalType); - for (int i = 1; i < types.Count; i++) { - var type = types[i]; - - // TypeDefUsers were sorted last so when we reach one, we can stop - if (type.GetType() != typeof(TypeDefMD)) { - while (i < types.Count) - newTypes.Add(types[i++]); - break; - } - - uint currRid = type.Rid; - int extraTypes = (int)(currRid - prevRid - 1); - if (extraTypes != 0) { // always >= 0 since currRid > prevRid - // At least one type has been removed. Create dummy types. - for (int j = 0; j < extraTypes; j++) - newTypes.Add(new TypeDefUser("dummy", Guid.NewGuid().ToString("B"), module.CorLibTypes.Object.TypeDefOrRef)); - } - newTypes.Add(type); - prevRid = currRid; - } - - var newTypesArray = newTypes.ToArray(); - InitializeTypeToRid(newTypesArray); - return newTypesArray; - } - - void InitializeTypeToRid(TypeDef[] types) { - uint rid = 1; - foreach (var type in types) { - if (type is null) - continue; - if (typeToRid.ContainsKey(type)) - continue; - typeToRid[type] = rid++; - } - } - - /// - protected override void AllocateTypeDefRids() { - foreach (var type in allTypeDefs) { - uint rid = tablesHeap.TypeDefTable.Create(new RawTypeDefRow()); - if (typeToRid[type] != rid) - throw new ModuleWriterException("Got a different rid than expected"); - } - } - - /// - /// Reserves rows in TypeRef, MemberRef, StandAloneSig, - /// TypeSpec and MethodSpec where we will store the original rows - /// to make sure they get the same rid. Any user created rows will be stored at - /// the end of each table. - /// - void CreateEmptyTableRows() { - uint rows; - - if (PreserveTypeRefRids) { - rows = mod.TablesStream.TypeRefTable.Rows; - for (uint i = 0; i < rows; i++) - tablesHeap.TypeRefTable.Create(new RawTypeRefRow()); - } - - if (PreserveMemberRefRids) { - rows = mod.TablesStream.MemberRefTable.Rows; - for (uint i = 0; i < rows; i++) - tablesHeap.MemberRefTable.Create(new RawMemberRefRow()); - } - - if (PreserveStandAloneSigRids) { - rows = mod.TablesStream.StandAloneSigTable.Rows; - for (uint i = 0; i < rows; i++) - tablesHeap.StandAloneSigTable.Create(new RawStandAloneSigRow()); - } - - if (PreserveTypeSpecRids) { - rows = mod.TablesStream.TypeSpecTable.Rows; - for (uint i = 0; i < rows; i++) - tablesHeap.TypeSpecTable.Create(new RawTypeSpecRow()); - } - - if (PreserveMethodSpecRids) { - rows = mod.TablesStream.MethodSpecTable.Rows; - for (uint i = 0; i < rows; i++) - tablesHeap.MethodSpecTable.Create(new RawMethodSpecRow()); - } - } - - /// - /// Adds any non-referenced rows that haven't been added yet but are present in - /// the original file. If there are any non-referenced rows, it's usually a sign - /// that an obfuscator has encrypted one or more methods or that it has added - /// some rows it uses to decrypt something. - /// - void InitializeUninitializedTableRows() { - InitializeTypeRefTableRows(); - InitializeMemberRefTableRows(); - InitializeStandAloneSigTableRows(); - InitializeTypeSpecTableRows(); - InitializeMethodSpecTableRows(); - } - - bool initdTypeRef = false; - void InitializeTypeRefTableRows() { - if (!PreserveTypeRefRids || initdTypeRef) - return; - initdTypeRef = true; - - uint rows = mod.TablesStream.TypeRefTable.Rows; - for (uint rid = 1; rid <= rows; rid++) - AddTypeRef(mod.ResolveTypeRef(rid)); - tablesHeap.TypeRefTable.ReAddRows(); - } - - bool initdMemberRef = false; - void InitializeMemberRefTableRows() { - if (!PreserveMemberRefRids || initdMemberRef) - return; - initdMemberRef = true; - - uint rows = mod.TablesStream.MemberRefTable.Rows; - for (uint rid = 1; rid <= rows; rid++) { - if (tablesHeap.MemberRefTable[rid].Class != 0) - continue; - AddMemberRef(mod.ResolveMemberRef(rid), true); - } - tablesHeap.MemberRefTable.ReAddRows(); - } - - bool initdStandAloneSig = false; - void InitializeStandAloneSigTableRows() { - if (!PreserveStandAloneSigRids || initdStandAloneSig) - return; - initdStandAloneSig = true; - - uint rows = mod.TablesStream.StandAloneSigTable.Rows; - for (uint rid = 1; rid <= rows; rid++) { - if (tablesHeap.StandAloneSigTable[rid].Signature != 0) - continue; - AddStandAloneSig(mod.ResolveStandAloneSig(rid), true); - } - tablesHeap.StandAloneSigTable.ReAddRows(); - } - - bool initdTypeSpec = false; - void InitializeTypeSpecTableRows() { - if (!PreserveTypeSpecRids || initdTypeSpec) - return; - initdTypeSpec = true; - - uint rows = mod.TablesStream.TypeSpecTable.Rows; - for (uint rid = 1; rid <= rows; rid++) { - if (tablesHeap.TypeSpecTable[rid].Signature != 0) - continue; - AddTypeSpec(mod.ResolveTypeSpec(rid), true); - } - tablesHeap.TypeSpecTable.ReAddRows(); - } - - bool initdMethodSpec = false; - void InitializeMethodSpecTableRows() { - if (!PreserveMethodSpecRids || initdMethodSpec) - return; - initdMethodSpec = true; - - uint rows = mod.TablesStream.MethodSpecTable.Rows; - for (uint rid = 1; rid <= rows; rid++) { - if (tablesHeap.MethodSpecTable[rid].Method != 0) - continue; - AddMethodSpec(mod.ResolveMethodSpec(rid), true); - } - tablesHeap.MethodSpecTable.ReAddRows(); - } - - /// - protected override void AllocateMemberDefRids() { - FindMemberDefs(); - - 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())) - throw new ModuleWriterException("Invalid field rid"); - } - - for (int i = 1; i <= methodDefInfos.TableSize; i++) { - if ((uint)i != tablesHeap.MethodTable.Create(new RawMethodRow())) - throw new ModuleWriterException("Invalid method rid"); - } - - for (int i = 1; i <= paramDefInfos.TableSize; i++) { - if ((uint)i != tablesHeap.ParamTable.Create(new RawParamRow())) - throw new ModuleWriterException("Invalid param rid"); - } - - for (int i = 1; i <= eventDefInfos.TableSize; i++) { - if ((uint)i != tablesHeap.EventTable.Create(new RawEventRow())) - throw new ModuleWriterException("Invalid event rid"); - } - - for (int i = 1; i <= propertyDefInfos.TableSize; i++) { - if ((uint)i != tablesHeap.PropertyTable.Create(new RawPropertyRow())) - throw new ModuleWriterException("Invalid property rid"); - } - - SortFields(); - SortMethods(); - SortParameters(); - SortEvents(); - SortProperties(); - - RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 1.0 / numEvents); - - if (fieldDefInfos.NeedPtrTable) { - for (int i = 0; i < fieldDefInfos.Count; i++) { - var info = fieldDefInfos.GetSorted(i); - if ((uint)i + 1 != tablesHeap.FieldPtrTable.Add(new RawFieldPtrRow(info.Rid))) - throw new ModuleWriterException("Invalid field ptr rid"); - } - ReUseDeletedFieldRows(); - } - - if (methodDefInfos.NeedPtrTable) { - for (int i = 0; i < methodDefInfos.Count; i++) { - var info = methodDefInfos.GetSorted(i); - if ((uint)i + 1 != tablesHeap.MethodPtrTable.Add(new RawMethodPtrRow(info.Rid))) - throw new ModuleWriterException("Invalid method ptr rid"); - } - ReUseDeletedMethodRows(); - } - - if (paramDefInfos.NeedPtrTable) { - // NOTE: peverify does not support the ParamPtr table. It's a bug. - for (int i = 0; i < paramDefInfos.Count; i++) { - var info = paramDefInfos.GetSorted(i); - if ((uint)i + 1 != tablesHeap.ParamPtrTable.Add(new RawParamPtrRow(info.Rid))) - throw new ModuleWriterException("Invalid param ptr rid"); - } - ReUseDeletedParamRows(); - } - - if (eventDefInfos.NeedPtrTable) { - for (int i = 0; i < eventDefInfos.Count; i++) { - var info = eventDefInfos.GetSorted(i); - if ((uint)i + 1 != tablesHeap.EventPtrTable.Add(new RawEventPtrRow(info.Rid))) - throw new ModuleWriterException("Invalid event ptr rid"); - } - } - - if (propertyDefInfos.NeedPtrTable) { - for (int i = 0; i < propertyDefInfos.Count; i++) { - var info = propertyDefInfos.GetSorted(i); - if ((uint)i + 1 != tablesHeap.PropertyPtrTable.Add(new RawPropertyPtrRow(info.Rid))) - throw new ModuleWriterException("Invalid property ptr rid"); - } - } - - RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 2.0 / numEvents); - - InitializeMethodAndFieldList(); - InitializeParamList(); - InitializeEventMap(); - InitializePropertyMap(); - - RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 3.0 / numEvents); - - // We must re-use deleted event/property rows after we've initialized - // the event/prop map tables. - if (eventDefInfos.NeedPtrTable) - ReUseDeletedEventRows(); - if (propertyDefInfos.NeedPtrTable) - ReUseDeletedPropertyRows(); - - RaiseProgress(Writer.MetadataEvent.AllocateMemberDefRids, 4.0 / numEvents); - - InitializeTypeRefTableRows(); - InitializeTypeSpecTableRows(); - InitializeMemberRefTableRows(); - InitializeMethodSpecTableRows(); - } - - /// - /// Re-uses all Field rows which aren't owned by any type due to the fields - /// having been deleted by the user. The reason we must do this is that the - /// FieldPtr and Field tables must be the same size. - /// - void ReUseDeletedFieldRows() { - if (tablesHeap.FieldPtrTable.IsEmpty) - return; - if (fieldDefInfos.TableSize == tablesHeap.FieldPtrTable.Rows) - return; - - var hasOwner = new bool[fieldDefInfos.TableSize]; - for (int i = 0; i < fieldDefInfos.Count; i++) - hasOwner[(int)fieldDefInfos.Get(i).Rid - 1] = true; - - CreateDummyPtrTableType(); - - uint fieldSig = GetSignature(new FieldSig(module.CorLibTypes.Byte)); - for (int i = 0; i < hasOwner.Length; i++) { - if (hasOwner[i]) - continue; - uint frid = (uint)i + 1; - - var frow = new RawFieldRow((ushort)(FieldAttributes.Public | FieldAttributes.Static), stringsHeap.Add($"f{frid:X6}"), fieldSig); - tablesHeap.FieldTable[frid] = frow; - tablesHeap.FieldPtrTable.Create(new RawFieldPtrRow(frid)); - } - - if (fieldDefInfos.TableSize != tablesHeap.FieldPtrTable.Rows) - throw new ModuleWriterException("Didn't create all dummy fields"); - } - - /// - /// Re-uses all Method rows which aren't owned by any type due to the methods - /// having been deleted by the user. The reason we must do this is that the - /// MethodPtr and Method tables must be the same size. - /// - void ReUseDeletedMethodRows() { - if (tablesHeap.MethodPtrTable.IsEmpty) - return; - if (methodDefInfos.TableSize == tablesHeap.MethodPtrTable.Rows) - return; - - var hasOwner = new bool[methodDefInfos.TableSize]; - for (int i = 0; i < methodDefInfos.Count; i++) - hasOwner[(int)methodDefInfos.Get(i).Rid - 1] = true; - - CreateDummyPtrTableType(); - - uint methodSig = GetSignature(MethodSig.CreateInstance(module.CorLibTypes.Void)); - for (int i = 0; i < hasOwner.Length; i++) { - if (hasOwner[i]) - continue; - uint mrid = (uint)i + 1; - - var mrow = new RawMethodRow(0, (ushort)(MethodImplAttributes.IL | MethodImplAttributes.Managed), - (ushort)(MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Abstract), - stringsHeap.Add($"m{mrid:X6}"), methodSig, (uint)paramDefInfos.Count); - tablesHeap.MethodTable[mrid] = mrow; - tablesHeap.MethodPtrTable.Create(new RawMethodPtrRow(mrid)); - } - - if (methodDefInfos.TableSize != tablesHeap.MethodPtrTable.Rows) - throw new ModuleWriterException("Didn't create all dummy methods"); - } - - /// - /// Re-uses all Param rows which aren't owned by any type due to the params - /// having been deleted by the user. The reason we must do this is that the - /// ParamPtr and Param tables must be the same size. - /// This method must be called after since - /// this method will create more methods at the end of the Method table. - /// - void ReUseDeletedParamRows() { - if (tablesHeap.ParamPtrTable.IsEmpty) - return; - if (paramDefInfos.TableSize == tablesHeap.ParamPtrTable.Rows) - return; - - var hasOwner = new bool[paramDefInfos.TableSize]; - for (int i = 0; i < paramDefInfos.Count; i++) - hasOwner[(int)paramDefInfos.Get(i).Rid - 1] = true; - - CreateDummyPtrTableType(); - - // For each param, attach it to a new method. Another alternative would be to create - // one (or a few) methods with tons of parameters. - uint methodSig = GetSignature(MethodSig.CreateInstance(module.CorLibTypes.Void)); - for (int i = 0; i < hasOwner.Length; i++) { - if (hasOwner[i]) - continue; - uint prid = (uint)i + 1; - - var prow = new RawParamRow(0, 0, stringsHeap.Add($"p{prid:X6}")); - tablesHeap.ParamTable[prid] = prow; - 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($"mp{prid:X6}"), - methodSig, - ptrRid); - uint mrid = tablesHeap.MethodTable.Create(mrow); - if (tablesHeap.MethodPtrTable.Rows > 0) - tablesHeap.MethodPtrTable.Create(new RawMethodPtrRow(mrid)); - } - - if (paramDefInfos.TableSize != tablesHeap.ParamPtrTable.Rows) - throw new ModuleWriterException("Didn't create all dummy params"); - } - - /// - /// Re-uses all Event rows which aren't owned by any type due to the events - /// having been deleted by the user. The reason we must do this is that the - /// EventPtr and Event tables must be the same size. - /// - void ReUseDeletedEventRows() { - if (tablesHeap.EventPtrTable.IsEmpty) - return; - if (eventDefInfos.TableSize == tablesHeap.EventPtrTable.Rows) - return; - - var hasOwner = new bool[eventDefInfos.TableSize]; - for (int i = 0; i < eventDefInfos.Count; i++) - hasOwner[(int)eventDefInfos.Get(i).Rid - 1] = true; - - uint typeRid = CreateDummyPtrTableType(); - tablesHeap.EventMapTable.Create(new RawEventMapRow(typeRid, (uint)tablesHeap.EventPtrTable.Rows + 1)); - - uint eventType = AddTypeDefOrRef(module.CorLibTypes.Object.TypeDefOrRef); - for (int i = 0; i < hasOwner.Length; i++) { - if (hasOwner[i]) - continue; - uint erid = (uint)i + 1; - - var frow = new RawEventRow(0, stringsHeap.Add($"E{erid:X6}"), eventType); - tablesHeap.EventTable[erid] = frow; - tablesHeap.EventPtrTable.Create(new RawEventPtrRow(erid)); - } - - if (eventDefInfos.TableSize != tablesHeap.EventPtrTable.Rows) - throw new ModuleWriterException("Didn't create all dummy events"); - } - - /// - /// Re-uses all Property rows which aren't owned by any type due to the properties - /// having been deleted by the user. The reason we must do this is that the - /// PropertyPtr and Property tables must be the same size. - /// - void ReUseDeletedPropertyRows() { - if (tablesHeap.PropertyPtrTable.IsEmpty) - return; - if (propertyDefInfos.TableSize == tablesHeap.PropertyPtrTable.Rows) - return; - - var hasOwner = new bool[propertyDefInfos.TableSize]; - for (int i = 0; i < propertyDefInfos.Count; i++) - hasOwner[(int)propertyDefInfos.Get(i).Rid - 1] = true; - - uint typeRid = CreateDummyPtrTableType(); - tablesHeap.PropertyMapTable.Create(new RawPropertyMapRow(typeRid, (uint)tablesHeap.PropertyPtrTable.Rows + 1)); - - uint propertySig = GetSignature(PropertySig.CreateStatic(module.CorLibTypes.Object)); - for (int i = 0; i < hasOwner.Length; i++) { - if (hasOwner[i]) - continue; - uint prid = (uint)i + 1; - - var frow = new RawPropertyRow(0, stringsHeap.Add($"P{prid:X6}"), propertySig); - tablesHeap.PropertyTable[prid] = frow; - tablesHeap.PropertyPtrTable.Create(new RawPropertyPtrRow(prid)); - } - - if (propertyDefInfos.TableSize != tablesHeap.PropertyPtrTable.Rows) - throw new ModuleWriterException("Didn't create all dummy properties"); - } - - /// - /// Creates a dummy TypeDef at the end of the TypeDef table that will own - /// dummy methods and fields. These dummy methods and fields are only created if the size - /// of the ptr table is less than the size of the non-ptr table (eg. size MethodPtr table - /// is less than size Method table). The only reason the ptr table would be smaller than - /// the non-ptr table is when some field/method has been deleted and we must preserve - /// all method/field rids. - /// - uint CreateDummyPtrTableType() { - if (dummyPtrTableTypeRid != 0) - return dummyPtrTableTypeRid; - - var flags = TypeAttributes.NotPublic | TypeAttributes.AutoLayout | - TypeAttributes.Class | TypeAttributes.Abstract | TypeAttributes.AnsiClass; - int numFields = fieldDefInfos.NeedPtrTable ? fieldDefInfos.Count : fieldDefInfos.TableSize; - int numMethods = methodDefInfos.NeedPtrTable ? methodDefInfos.Count : methodDefInfos.TableSize; - var row = new RawTypeDefRow((uint)flags, - stringsHeap.Add(Guid.NewGuid().ToString("B")), - stringsHeap.Add("dummy_ptr"), - AddTypeDefOrRef(module.CorLibTypes.Object.TypeDefOrRef), - (uint)numFields + 1, - (uint)numMethods + 1); - dummyPtrTableTypeRid = tablesHeap.TypeDefTable.Create(row); - if (dummyPtrTableTypeRid == 1) - throw new ModuleWriterException("Dummy ptr type is the first type"); - return dummyPtrTableTypeRid; - } - uint dummyPtrTableTypeRid; - - void FindMemberDefs() { - int count; - var added = new Dictionary(); - int pos; - foreach (var type in allTypeDefs) { - if (type is null) - continue; - - pos = 0; - var fields = type.Fields; - count = fields.Count; - for (int i = 0; i < count; i++) { - var field = fields[i]; - if (field is null) - continue; - fieldDefInfos.Add(field, pos++); - } - - pos = 0; - var methods = type.Methods; - count = methods.Count; - for (int i = 0; i < count; i++) { - var method = methods[i]; - if (method is null) - continue; - methodDefInfos.Add(method, pos++); - } - - pos = 0; - var events = type.Events; - count = events.Count; - for (int i = 0; i < count; i++) { - var evt = events[i]; - if (evt is null || added.ContainsKey(evt)) - continue; - added[evt] = true; - eventDefInfos.Add(evt, pos++); - } - - pos = 0; - var properties = type.Properties; - count = properties.Count; - for (int i = 0; i < count; i++) { - var prop = properties[i]; - if (prop is null || added.ContainsKey(prop)) - continue; - added[prop] = true; - propertyDefInfos.Add(prop, pos++); - } - } - - fieldDefInfos.SortDefs(); - methodDefInfos.SortDefs(); - eventDefInfos.SortDefs(); - propertyDefInfos.SortDefs(); - - for (int i = 0; i < methodDefInfos.Count; i++) { - var method = methodDefInfos.Get(i).Def; - pos = 0; - foreach (var param in Sort(method.ParamDefs)) { - if (param is null) - continue; - paramDefInfos.Add(param, pos++); - } - } - paramDefInfos.SortDefs(); - } - - void SortFields() => - fieldDefInfos.Sort((a, b) => { - 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) - return dta.CompareTo(dtb); - return fieldDefInfos.GetCollectionPosition(a.Def).CompareTo(fieldDefInfos.GetCollectionPosition(b.Def)); - }); - - void SortMethods() => - methodDefInfos.Sort((a, b) => { - 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) - return dta.CompareTo(dtb); - return methodDefInfos.GetCollectionPosition(a.Def).CompareTo(methodDefInfos.GetCollectionPosition(b.Def)); - }); - - void SortParameters() => - paramDefInfos.Sort((a, b) => { - 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) - return dma.CompareTo(dmb); - return paramDefInfos.GetCollectionPosition(a.Def).CompareTo(paramDefInfos.GetCollectionPosition(b.Def)); - }); - - void SortEvents() => - eventDefInfos.Sort((a, b) => { - 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) - return dta.CompareTo(dtb); - return eventDefInfos.GetCollectionPosition(a.Def).CompareTo(eventDefInfos.GetCollectionPosition(b.Def)); - }); - - void SortProperties() => - propertyDefInfos.Sort((a, b) => { - 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) - return dta.CompareTo(dtb); - return propertyDefInfos.GetCollectionPosition(a.Def).CompareTo(propertyDefInfos.GetCollectionPosition(b.Def)); - }); - - void InitializeMethodAndFieldList() { - uint fieldList = 1, methodList = 1; - foreach (var type in allTypeDefs) { - uint index = typeToRid[type]; - var typeRow = tablesHeap.TypeDefTable[index]; - typeRow = new RawTypeDefRow(typeRow.Flags, typeRow.Name, typeRow.Namespace, typeRow.Extends, fieldList, methodList); - tablesHeap.TypeDefTable[index] = typeRow; - fieldList += (uint)type.Fields.Count; - methodList += (uint)type.Methods.Count; - } - } - - void InitializeParamList() { - uint ridList = 1; - for (uint methodRid = 1; methodRid <= methodDefInfos.TableSize; methodRid++) { - var methodInfo = methodDefInfos.GetByRid(methodRid); - 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 not null) - ridList += (uint)methodInfo.Def.ParamDefs.Count; - } - } - - void InitializeEventMap() { - if (!tablesHeap.EventMapTable.IsEmpty) - throw new ModuleWriterException("EventMap table isn't empty"); - TypeDef type = null; - for (int i = 0; i < eventDefInfos.Count; i++) { - var info = eventDefInfos.GetSorted(i); - if (type == info.Def.DeclaringType) - continue; - type = info.Def.DeclaringType; - var row = new RawEventMapRow(typeToRid[type], info.NewRid); - uint eventMapRid = tablesHeap.EventMapTable.Create(row); - eventMapInfos.Add(type, eventMapRid); - } - } - - void InitializePropertyMap() { - if (!tablesHeap.PropertyMapTable.IsEmpty) - throw new ModuleWriterException("PropertyMap table isn't empty"); - TypeDef type = null; - for (int i = 0; i < propertyDefInfos.Count; i++) { - var info = propertyDefInfos.GetSorted(i); - if (type == info.Def.DeclaringType) - continue; - type = info.Def.DeclaringType; - var row = new RawPropertyMapRow(typeToRid[type], info.NewRid); - uint propertyMapRid = tablesHeap.PropertyMapTable.Create(row); - propertyMapInfos.Add(type, propertyMapRid); - } - } - - /// - protected override uint AddTypeRef(TypeRef tr) { - if (tr is null) { - Error("TypeRef is null"); - return 0; - } - if (typeRefInfos.TryGetRid(tr, out uint rid)) { - if (rid == 0) - Error("TypeRef 0x{0:X8} has an infinite ResolutionScope loop.", tr.MDToken.Raw); - return rid; - } - typeRefInfos.Add(tr, 0); // Prevent inf recursion - - bool isOld = PreserveTypeRefRids && mod.ResolveTypeRef(tr.Rid) == tr; - var row = new RawTypeRefRow(AddResolutionScope(tr.ResolutionScope), stringsHeap.Add(tr.Name), stringsHeap.Add(tr.Namespace)); - if (isOld) { - rid = tr.Rid; - tablesHeap.TypeRefTable[tr.Rid] = row; - } - else - rid = tablesHeap.TypeRefTable.Add(row); - typeRefInfos.SetRid(tr, rid); - AddCustomAttributes(Table.TypeRef, rid, tr); - AddCustomDebugInformationList(Table.TypeRef, rid, tr); - return rid; - } - - /// - protected override uint AddTypeSpec(TypeSpec ts) => AddTypeSpec(ts, false); - - uint AddTypeSpec(TypeSpec ts, bool forceIsOld) { - if (ts is null) { - Error("TypeSpec is null"); - return 0; - } - if (typeSpecInfos.TryGetRid(ts, out uint rid)) { - if (rid == 0) - Error("TypeSpec 0x{0:X8} has an infinite TypeSig loop.", ts.MDToken.Raw); - return rid; - } - typeSpecInfos.Add(ts, 0); // Prevent inf recursion - - bool isOld = forceIsOld || (PreserveTypeSpecRids && mod.ResolveTypeSpec(ts.Rid) == ts); - var row = new RawTypeSpecRow(GetSignature(ts.TypeSig, ts.ExtraData)); - if (isOld) { - rid = ts.Rid; - tablesHeap.TypeSpecTable[ts.Rid] = row; - } - else - rid = tablesHeap.TypeSpecTable.Add(row); - typeSpecInfos.SetRid(ts, rid); - AddCustomAttributes(Table.TypeSpec, rid, ts); - AddCustomDebugInformationList(Table.TypeSpec, rid, ts); - return rid; - } - - /// - protected override uint AddMemberRef(MemberRef mr) => AddMemberRef(mr, false); - - uint AddMemberRef(MemberRef mr, bool forceIsOld) { - if (mr is null) { - Error("MemberRef is null"); - return 0; - } - if (memberRefInfos.TryGetRid(mr, out uint rid)) - return rid; - - bool isOld = forceIsOld || (PreserveMemberRefRids && mod.ResolveMemberRef(mr.Rid) == mr); - var row = new RawMemberRefRow(AddMemberRefParent(mr.Class), stringsHeap.Add(mr.Name), GetSignature(mr.Signature)); - if (isOld) { - rid = mr.Rid; - tablesHeap.MemberRefTable[mr.Rid] = row; - } - else - rid = tablesHeap.MemberRefTable.Add(row); - memberRefInfos.Add(mr, rid); - AddCustomAttributes(Table.MemberRef, rid, mr); - AddCustomDebugInformationList(Table.MemberRef, rid, mr); - return rid; - } - - /// - protected override uint AddStandAloneSig(StandAloneSig sas) => AddStandAloneSig(sas, false); - - uint AddStandAloneSig(StandAloneSig sas, bool forceIsOld) { - if (sas is null) { - Error("StandAloneSig is null"); - return 0; - } - if (standAloneSigInfos.TryGetRid(sas, out uint rid)) - return rid; - - bool isOld = forceIsOld || (PreserveStandAloneSigRids && mod.ResolveStandAloneSig(sas.Rid) == sas); - var row = new RawStandAloneSigRow(GetSignature(sas.Signature)); - if (isOld) { - rid = sas.Rid; - tablesHeap.StandAloneSigTable[sas.Rid] = row; - } - else - rid = tablesHeap.StandAloneSigTable.Add(row); - standAloneSigInfos.Add(sas, rid); - AddCustomAttributes(Table.StandAloneSig, rid, sas); - AddCustomDebugInformationList(Table.StandAloneSig, rid, sas); - return rid; - } - - /// - public override MDToken GetToken(IList locals, uint origToken) { - if (!PreserveStandAloneSigRids || !IsValidStandAloneSigToken(origToken)) - return base.GetToken(locals, origToken); - - uint rid = AddStandAloneSig(new LocalSig(locals, false), origToken); - if (rid == 0) - return base.GetToken(locals, origToken); - return new MDToken(Table.StandAloneSig, rid); - } - - /// - protected override uint AddStandAloneSig(MethodSig methodSig, uint origToken) { - if (!PreserveStandAloneSigRids || !IsValidStandAloneSigToken(origToken)) - return base.AddStandAloneSig(methodSig, origToken); - - uint rid = AddStandAloneSig(methodSig, origToken); - if (rid == 0) - return base.AddStandAloneSig(methodSig, 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); - if (callConvTokenToSignature.TryGetValue(origToken, out uint otherSig)) { - if (sig == otherSig) - return MDToken.ToRID(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 0x{0:X8} already exists", origToken); - return 0; - } - - // Make sure it uses the updated sig - var oldSig = sas.Signature; - try { - sas.Signature = callConvSig; - AddStandAloneSig(sas, true); - } - finally { - sas.Signature = oldSig; - } - - callConvTokenToSignature.Add(origToken, sig); - return MDToken.ToRID(origToken); - } - - bool IsValidStandAloneSigToken(uint token) { - if (MDToken.ToTable(token) != Table.StandAloneSig) - return false; - uint rid = MDToken.ToRID(token); - return mod.TablesStream.StandAloneSigTable.IsValidRID(rid); - } - - /// - protected override uint AddMethodSpec(MethodSpec ms) => AddMethodSpec(ms, false); - - uint AddMethodSpec(MethodSpec ms, bool forceIsOld) { - if (ms is null) { - Error("MethodSpec is null"); - return 0; - } - if (methodSpecInfos.TryGetRid(ms, out uint rid)) - return rid; - - bool isOld = forceIsOld || (PreserveMethodSpecRids && mod.ResolveMethodSpec(ms.Rid) == ms); - var row = new RawMethodSpecRow(AddMethodDefOrRef(ms.Method), GetSignature(ms.Instantiation)); - if (isOld) { - rid = ms.Rid; - tablesHeap.MethodSpecTable[ms.Rid] = row; - } - else - rid = tablesHeap.MethodSpecTable.Add(row); - methodSpecInfos.Add(ms, rid); - AddCustomAttributes(Table.MethodSpec, rid, ms); - AddCustomDebugInformationList(Table.MethodSpec, rid, ms); - return rid; - } - - /// - protected override void BeforeSortingCustomAttributes() => InitializeUninitializedTableRows(); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/RelocDirectory.cs b/Plugins/dnlib/DotNet/Writer/RelocDirectory.cs deleted file mode 100644 index 6b7d4c0..0000000 --- a/Plugins/dnlib/DotNet/Writer/RelocDirectory.cs +++ /dev/null @@ -1,123 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -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; - - readonly struct RelocInfo { - public readonly IChunk Chunk; - public readonly uint OffsetOrRva; - public RelocInfo(IChunk chunk, uint offset) { - Chunk = chunk; - OffsetOrRva = offset; - } - } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - internal bool NeedsRelocSection => 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 is not 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 is not null) - totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); - pageList = new List(); - relocSections.Add(pageList); - } - pageList.Add(relocRva); - } - if (pageList is not null) - totalSize += (uint)(8 + ((pageList.Count + 1) & ~1) * 2); - } - - /// - public uint GetFileLength() => totalSize; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - bool is64bit = machine.Is64Bit(); - // 3 = IMAGE_REL_BASED_HIGHLOW, A = IMAGE_REL_BASED_DIR64 - uint relocType = is64bit ? 0xA000U : 0x3000; - foreach (var pageList in relocSections) { - writer.WriteUInt32(pageList[0] & ~0xFFFU); - writer.WriteUInt32((uint)(8 + ((pageList.Count + 1) & ~1) * 2)); - foreach (var rva in pageList) - writer.WriteUInt16((ushort)(relocType | (rva & 0xFFF))); - if ((pageList.Count & 1) != 0) - writer.WriteUInt16(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/Plugins/dnlib/DotNet/Writer/RoslynContentIdProvider.cs b/Plugins/dnlib/DotNet/Writer/RoslynContentIdProvider.cs deleted file mode 100644 index f8f4665..0000000 --- a/Plugins/dnlib/DotNet/Writer/RoslynContentIdProvider.cs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/Plugins/dnlib/DotNet/Writer/SectionSizes.cs b/Plugins/dnlib/DotNet/Writer/SectionSizes.cs deleted file mode 100644 index e5a8f9f..0000000 --- a/Plugins/dnlib/DotNet/Writer/SectionSizes.cs +++ /dev/null @@ -1,71 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; - -namespace dnlib.DotNet.Writer { - readonly struct SectionSizeInfo { - /// - /// Length of section - /// - public readonly uint length; - - /// - /// Section characteristics - /// - public readonly uint characteristics; - - /// - /// Constructor - /// - /// Length of section - /// Section characteristics - public SectionSizeInfo(uint length, uint characteristics) { - this.length = length; - this.characteristics = characteristics; - } - } - - /// - /// Calculates the optional header section sizes - /// - readonly struct SectionSizes { - public readonly uint SizeOfHeaders; - public readonly uint SizeOfImage; - 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 = GetSizeOfHeaders(fileAlignment, headerLen); - SizeOfImage = Utils.AlignUp(SizeOfHeaders, sectionAlignment); - BaseOfData = 0; - BaseOfCode = 0; - SizeOfCode = 0; - SizeOfInitdData = 0; - SizeOfUninitdData = 0; - foreach (var section in getSectionSizeInfos()) { - uint sectAlignedVs = Utils.AlignUp(section.length, sectionAlignment); - uint fileAlignedVs = Utils.AlignUp(section.length, fileAlignment); - - bool isCode = (section.characteristics & 0x20) != 0; - bool isInitdData = (section.characteristics & 0x40) != 0; - bool isUnInitdData = (section.characteristics & 0x80) != 0; - - if (BaseOfCode == 0 && isCode) - BaseOfCode = SizeOfImage; - if (BaseOfData == 0 && (isInitdData || isUnInitdData)) - BaseOfData = SizeOfImage; - if (isCode) - SizeOfCode += fileAlignedVs; - if (isInitdData) - SizeOfInitdData += fileAlignedVs; - if (isUnInitdData) - SizeOfUninitdData += fileAlignedVs; - - SizeOfImage += sectAlignedVs; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/SerializerMethodContext.cs b/Plugins/dnlib/DotNet/Writer/SerializerMethodContext.cs deleted file mode 100644 index 42671ec..0000000 --- a/Plugins/dnlib/DotNet/Writer/SerializerMethodContext.cs +++ /dev/null @@ -1,63 +0,0 @@ -// 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 => body is not 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; - body = method?.Body; - dictInitd = false; - } - } - - public uint GetOffset(Instruction instr) { - if (!dictInitd) { - Debug.Assert(body is not null); - if (body is null) - return 0; - InitializeDict(); - } - if (instr is null) - return bodySize; - 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) => this.method == method; - - void InitializeDict() { - Debug.Assert(body is not 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/Plugins/dnlib/DotNet/Writer/SignatureWriter.cs b/Plugins/dnlib/DotNet/Writer/SignatureWriter.cs deleted file mode 100644 index b045461..0000000 --- a/Plugins/dnlib/DotNet/Writer/SignatureWriter.cs +++ /dev/null @@ -1,349 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; - -namespace dnlib.DotNet.Writer { - /// - /// Helps map s to tokens - /// - public interface ISignatureWriterHelper : IWriterError { - /// - /// Returns a TypeDefOrRef encoded token - /// - /// A TypeDefOrRef type - uint ToEncodedToken(ITypeDefOrRef typeDefOrRef); - } - - /// - /// Writes signatures - /// - public struct SignatureWriter : IDisposable { - readonly ISignatureWriterHelper helper; - RecursionCounter recursionCounter; - readonly MemoryStream outStream; - readonly DataWriter writer; - readonly bool disposeStream; - - /// - /// Write a signature - /// - /// Helper - /// The type - /// The signature as a byte array - public static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig) { - using (var writer = new SignatureWriter(helper)) { - writer.Write(typeSig); - return writer.GetResult(); - } - } - - internal static byte[] Write(ISignatureWriterHelper helper, TypeSig typeSig, DataWriterContext context) { - using (var writer = new SignatureWriter(helper, context)) { - writer.Write(typeSig); - return writer.GetResult(); - } - } - - /// - /// Write a signature - /// - /// Helper - /// The signature - /// The signature as a byte array - public static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig sig) { - using (var writer = new SignatureWriter(helper)) { - writer.Write(sig); - return writer.GetResult(); - } - } - - internal static byte[] Write(ISignatureWriterHelper helper, CallingConventionSig sig, DataWriterContext context) { - using (var writer = new SignatureWriter(helper, context)) { - writer.Write(sig); - return writer.GetResult(); - } - } - - SignatureWriter(ISignatureWriterHelper helper) { - this.helper = helper; - recursionCounter = new RecursionCounter(); - outStream = new MemoryStream(); - writer = new DataWriter(outStream); - disposeStream = true; - } - - SignatureWriter(ISignatureWriterHelper helper, DataWriterContext context) { - this.helper = helper; - recursionCounter = new RecursionCounter(); - outStream = context.OutStream; - writer = context.Writer; - disposeStream = false; - outStream.SetLength(0); - outStream.Position = 0; - } - - 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; - if (typeSig is null) { - helper.Error("TypeSig is null"); - writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); - return; - } - - uint count; - switch (typeSig.ElementType) { - case ElementType.Void: - 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: - case ElementType.R4: - case ElementType.R8: - case ElementType.String: - case ElementType.TypedByRef: - case ElementType.I: - case ElementType.U: - case ElementType.Object: - case ElementType.Sentinel: - writer.WriteByte((byte)typeSig.ElementType); - break; - - case ElementType.Ptr: - case ElementType.ByRef: - case ElementType.SZArray: - case ElementType.Pinned: - writer.WriteByte((byte)typeSig.ElementType); - Write(typeSig.Next); - break; - - case ElementType.ValueType: - case ElementType.Class: - writer.WriteByte((byte)typeSig.ElementType); - Write(((TypeDefOrRefSig)typeSig).TypeDefOrRef); - break; - - case ElementType.Var: - case ElementType.MVar: - writer.WriteByte((byte)typeSig.ElementType); - WriteCompressedUInt32(((GenericSig)typeSig).Number); - break; - - case ElementType.Array: - writer.WriteByte((byte)typeSig.ElementType); - var ary = (ArraySig)typeSig; - Write(ary.Next); - WriteCompressedUInt32(ary.Rank); - if (ary.Rank == 0) - break; - count = WriteCompressedUInt32((uint)ary.Sizes.Count); - for (uint i = 0; i < count; i++) - WriteCompressedUInt32(ary.Sizes[(int)i]); - count = WriteCompressedUInt32((uint)ary.LowerBounds.Count); - for (uint i = 0; i < count; i++) - WriteCompressedInt32(ary.LowerBounds[(int)i]); - break; - - case ElementType.GenericInst: - writer.WriteByte((byte)typeSig.ElementType); - var gis = (GenericInstSig)typeSig; - Write(gis.GenericType); - count = WriteCompressedUInt32((uint)gis.GenericArguments.Count); - for (uint i = 0; i < count; i++) - Write(gis.GenericArguments[(int)i]); - break; - - case ElementType.ValueArray: - writer.WriteByte((byte)typeSig.ElementType); - Write(typeSig.Next); - WriteCompressedUInt32((typeSig as ValueArraySig).Size); - break; - - case ElementType.FnPtr: - writer.WriteByte((byte)typeSig.ElementType); - Write((typeSig as FnPtrSig).Signature); - break; - - case ElementType.CModReqd: - case ElementType.CModOpt: - writer.WriteByte((byte)typeSig.ElementType); - Write((typeSig as ModifierSig).Modifier); - Write(typeSig.Next); - break; - - case ElementType.Module: - writer.WriteByte((byte)typeSig.ElementType); - WriteCompressedUInt32((typeSig as ModuleSig).Index); - Write(typeSig.Next); - break; - - case ElementType.End: - case ElementType.R: - case ElementType.Internal: - default: - helper.Error("Unknown or unsupported element type"); - writer.WriteByte((byte)DEFAULT_ELEMENT_TYPE); - break; - } - - recursionCounter.Decrement(); - } - - void Write(ITypeDefOrRef tdr) { - if (tdr is null) { - helper.Error("TypeDefOrRef is null"); - WriteCompressedUInt32(0); - return; - } - - uint encodedToken = helper.ToEncodedToken(tdr); - if (encodedToken > 0x1FFFFFFF) { - helper.Error("Encoded token doesn't fit in 29 bits"); - encodedToken = 0; - } - WriteCompressedUInt32(encodedToken); - } - - void Write(CallingConventionSig sig) { - if (sig is null) { - helper.Error("sig is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - MethodBaseSig mbs; - FieldSig fs; - LocalSig ls; - GenericInstMethodSig gim; - - if ((mbs = sig as MethodBaseSig) is not null) - Write(mbs); - else if ((fs = sig as FieldSig) is not null) - Write(fs); - else if ((ls = sig as LocalSig) is not null) - Write(ls); - else if ((gim = sig as GenericInstMethodSig) is not null) - Write(gim); - else { - helper.Error("Unknown calling convention sig"); - writer.WriteByte((byte)sig.GetCallingConvention()); - } - - recursionCounter.Decrement(); - } - - void Write(MethodBaseSig sig) { - if (sig is null) { - helper.Error("sig is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - writer.WriteByte((byte)sig.GetCallingConvention()); - if (sig.Generic) - WriteCompressedUInt32(sig.GenParamCount); - - uint numParams = (uint)sig.Params.Count; - if (sig.ParamsAfterSentinel is not null) - numParams += (uint)sig.ParamsAfterSentinel.Count; - - uint count = WriteCompressedUInt32(numParams); - Write(sig.RetType); - for (uint i = 0; i < count && i < (uint)sig.Params.Count; i++) - Write(sig.Params[(int)i]); - - 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]); - } - - recursionCounter.Decrement(); - } - - void Write(FieldSig sig) { - if (sig is null) { - helper.Error("sig is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - writer.WriteByte((byte)sig.GetCallingConvention()); - Write(sig.Type); - - recursionCounter.Decrement(); - } - - void Write(LocalSig sig) { - if (sig is null) { - helper.Error("sig is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - writer.WriteByte((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]); - - recursionCounter.Decrement(); - } - - void Write(GenericInstMethodSig sig) { - if (sig is null) { - helper.Error("sig is null"); - return; - } - if (!recursionCounter.Increment()) { - helper.Error("Infinite recursion"); - return; - } - - writer.WriteByte((byte)sig.GetCallingConvention()); - uint count = WriteCompressedUInt32((uint)sig.GenericArguments.Count); - for (uint i = 0; i < count; i++) - Write(sig.GenericArguments[(int)i]); - - recursionCounter.Decrement(); - } - - /// - public void Dispose() { - if (!disposeStream) - return; - if (outStream is not null) - outStream.Dispose(); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/StartupStub.cs b/Plugins/dnlib/DotNet/Writer/StartupStub.cs deleted file mode 100644 index fc212ce..0000000 --- a/Plugins/dnlib/DotNet/Writer/StartupStub.cs +++ /dev/null @@ -1,97 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; -using dnlib.PE; - -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 Action logError; - FileOffset offset; - RVA rva; - - /// - /// Gets/sets the - /// - public ImportDirectory ImportDirectory { get; set; } - - /// - /// Gets/sets the - /// - public PEHeaders PEHeaders { get; set; } - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Gets the address of the JMP instruction - /// - public RVA EntryPointRVA => rva + (cpuArch is null ? 0 : cpuArch.GetStubCodeOffset(stubType)); - - internal bool Enable { get; set; } - internal uint Alignment => cpuArch is null ? 1 : cpuArch.GetStubAlignment(stubType); - - /// - /// Constructor - /// - /// Reloc directory - /// Machine - /// Error logger - internal StartupStub(RelocDirectory relocDirectory, Machine machine, Action logError) { - this.relocDirectory = relocDirectory; - this.machine = machine; - this.logError = logError; - CpuArch.TryGetCpuArch(machine, out cpuArch); - } - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - - if (!Enable) - return; - - 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; - } - - cpuArch.WriteStubRelocs(stubType, relocDirectory, this, 0); - } - - /// - public uint GetFileLength() { - if (!Enable) - return 0; - if (cpuArch is null) - return 0; - return cpuArch.GetStubSize(stubType); - } - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - if (!Enable) - return; - if (cpuArch is null) - return; - cpuArch.WriteStub(stubType, writer, PEHeaders.ImageBase, (uint)rva, (uint)ImportDirectory.IatCorXxxMainRVA); - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/StringsHeap.cs b/Plugins/dnlib/DotNet/Writer/StringsHeap.cs deleted file mode 100644 index 6a2a9d3..0000000 --- a/Plugins/dnlib/DotNet/Writer/StringsHeap.cs +++ /dev/null @@ -1,249 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.DotNet.MD; -using System.Diagnostics; -using System.IO; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// #Strings heap - /// - public sealed class StringsHeap : HeapBase, IOffsetHeap { - readonly Dictionary cachedDict = new Dictionary(UTF8StringEqualityComparer.Instance); - readonly List cached = new List(); - 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() => $"{StringsId:X8} {StringsOffset:X4} {Value.String}"; - } - - /// - public override string Name => "#Strings"; - - /// - /// Populates strings from an existing (eg. to preserve - /// string offsets) - /// - /// The #Strings stream with the original content - public void Populate(StringsStream stringsStream) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); - if (originalData is not null) - throw new InvalidOperationException("Can't call method twice"); - if (nextOffset != 1) - throw new InvalidOperationException("Add() has already been called"); - if (stringsStream is null || stringsStream.StreamLength == 0) - return; - - var reader = stringsStream.CreateReader(); - originalData = reader.ToArray(); - nextOffset = (uint)originalData.Length; - Populate(ref reader); - } - - void Populate(ref DataReader reader) { - reader.Position = 1; - while (reader.Position < reader.Length) { - uint offset = (uint)reader.Position; - var bytes = reader.TryReadBytesUntil(0); - if (bytes is null) - break; - - reader.ReadByte(); // terminating zero - if (bytes.Length == 0) - continue; - - var s = new UTF8String(bytes); - if (!cachedDict.ContainsKey(s)) - cachedDict[s] = offset; - } - } - - internal void AddOptimizedStringsAndSetReadOnly() { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #Strings when it's read-only"); - SetReadOnly(); - - stringsOffsetInfos.Sort(Comparison_StringsOffsetInfoSorter); - - StringsOffsetInfo prevInfo = null; - foreach (var info in stringsOffsetInfos) { - 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); - 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. The returned value is not necessarily an offset in - /// the #Strings heap. Call to get the offset. - /// - /// The string - /// 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; - - if (toStringsOffsetInfo.TryGetValue(s, out var info)) - return info.StringsId; - if (cachedDict.TryGetValue(s, out uint offset)) - return offset; - - 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; - if (offsetIdToInfo.TryGetValue(offsetId, out var info)) { - Debug.Assert(info.StringsOffset != 0); - return info.StringsOffset; - } - throw new ArgumentOutOfRangeException(nameof(offsetId)); - } - - /// - /// Adds a string to the #Strings heap, but does not re-use an existing position - /// - /// The string - /// The offset of the string in the #Strings heap - public uint Create(UTF8String s) { - if (isReadOnly) - 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) { - uint offset; - cached.Add(s); - cachedDict[s] = offset = nextOffset; - nextOffset += (uint)s.Data.Length + 1; - return offset; - } - - /// - public override uint GetRawLength() => nextOffset; - - - protected override EncryptionMethod GetEncryptionMethod(IEncryption e) => e.StringEnc; - - /// - protected override void WriteToImpl(DataWriter writer) { - if (originalData is not null) - writer.WriteBytes(originalData); - else - writer.WriteByte(0); - - uint offset = originalData is not null ? (uint)originalData.Length : 1; - foreach (var s in cached) { - 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); - } - else { - writer.WriteBytes(s.Data); - writer.WriteByte(0); - } - offset += (uint)s.Data.Length + 1; - } - } - - /// - public int GetRawDataSize(UTF8String data) => data.Data.Length + 1; - - /// - public void SetRawData(uint offset, byte[] rawData) { - if (userRawData is null) - userRawData = new Dictionary(); - userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); - } - - /// - public IEnumerable> GetAllRawData() { - 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); - yield return new KeyValuePair(offset, rawData); - offset += (uint)rawData.Length; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/StrongNameSignature.cs b/Plugins/dnlib/DotNet/Writer/StrongNameSignature.cs deleted file mode 100644 index c485cba..0000000 --- a/Plugins/dnlib/DotNet/Writer/StrongNameSignature.cs +++ /dev/null @@ -1,47 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Strong name signature chunk - /// - public sealed class StrongNameSignature : IReuseChunk { - FileOffset offset; - RVA rva; - int size; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Constructor - /// - /// Size of strong name signature - public StrongNameSignature(int size) => this.size = size; - - bool IReuseChunk.CanReuse(RVA origRva, uint origSize) => (uint)size <= origSize; - - /// - public void SetOffset(FileOffset offset, RVA rva) { - this.offset = offset; - this.rva = rva; - } - - /// - public uint GetFileLength() => (uint)size; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) => writer.WriteZeroes(size); - } -} diff --git a/Plugins/dnlib/DotNet/Writer/TablesHeap.cs b/Plugins/dnlib/DotNet/Writer/TablesHeap.cs deleted file mode 100644 index 6e23d70..0000000 --- a/Plugins/dnlib/DotNet/Writer/TablesHeap.cs +++ /dev/null @@ -1,532 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; -using dnlib.PE; -using dnlib.DotNet.MD; -using System; -using System.Collections.Generic; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// options - /// - public sealed class TablesHeapOptions { - /// - /// Should be 0 - /// - public uint? Reserved1; - - /// - /// Major version number. Default is 2. Valid versions are v1.0 (no generics), - /// v1.1 (generics are supported), or v2.0 (recommended). - /// - public byte? MajorVersion; - - /// - /// Minor version number. Default is 0. - /// - public byte? MinorVersion; - - /// - /// Force #- or #~ stream. Default value is null and recommended because the correct - /// tables stream will be used. true will force #- (Edit N' Continue) - /// stream, and false will force #~ (normal compressed) stream. - /// - 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 - /// - public uint? ExtraData; - - /// - /// Log2Rid to write - /// - public byte? Log2Rid; - - /// - /// true if there are deleted s, s, - /// s, s, s and/or - /// s. - /// - public bool? HasDeletedRows; - - /// - /// Creates portable PDB v1.0 options - /// - /// - public static TablesHeapOptions CreatePortablePdbV1_0() => - new TablesHeapOptions { - Reserved1 = 0, - MajorVersion = 2, - MinorVersion = 0, - UseENC = null, - ExtraData = null, - Log2Rid = null, - HasDeletedRows = null, - }; - } - - /// - /// Contains all .NET tables - /// - public sealed class TablesHeap : IHeap { - uint length; - byte majorVersion; - byte minorVersion; - bool bigStrings; - bool bigGuid; - bool bigBlob; - bool hasDeletedRows; - readonly Metadata metadata; - readonly TablesHeapOptions options; - FileOffset offset; - RVA rva; - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - -#pragma warning disable 1591 // XML doc comment - public readonly MDTable ModuleTable = new MDTable(Table.Module, RawRowEqualityComparer.Instance); - public readonly MDTable TypeRefTable = new MDTable(Table.TypeRef, RawRowEqualityComparer.Instance); - public readonly MDTable TypeDefTable = new MDTable(Table.TypeDef, RawRowEqualityComparer.Instance); - public readonly MDTable FieldPtrTable = new MDTable(Table.FieldPtr, RawRowEqualityComparer.Instance); - public readonly MDTable FieldTable = new MDTable(Table.Field, RawRowEqualityComparer.Instance); - public readonly MDTable MethodPtrTable = new MDTable(Table.MethodPtr, RawRowEqualityComparer.Instance); - public readonly MDTable MethodTable = new MDTable(Table.Method, RawRowEqualityComparer.Instance); - public readonly MDTable ParamPtrTable = new MDTable(Table.ParamPtr, RawRowEqualityComparer.Instance); - public readonly MDTable ParamTable = new MDTable(Table.Param, RawRowEqualityComparer.Instance); - public readonly MDTable InterfaceImplTable = new MDTable(Table.InterfaceImpl, RawRowEqualityComparer.Instance); - public readonly MDTable MemberRefTable = new MDTable(Table.MemberRef, RawRowEqualityComparer.Instance); - public readonly MDTable ConstantTable = new MDTable(Table.Constant, RawRowEqualityComparer.Instance); - public readonly MDTable CustomAttributeTable = new MDTable(Table.CustomAttribute, RawRowEqualityComparer.Instance); - public readonly MDTable FieldMarshalTable = new MDTable(Table.FieldMarshal, RawRowEqualityComparer.Instance); - public readonly MDTable DeclSecurityTable = new MDTable(Table.DeclSecurity, RawRowEqualityComparer.Instance); - public readonly MDTable ClassLayoutTable = new MDTable(Table.ClassLayout, RawRowEqualityComparer.Instance); - public readonly MDTable FieldLayoutTable = new MDTable(Table.FieldLayout, RawRowEqualityComparer.Instance); - public readonly MDTable StandAloneSigTable = new MDTable(Table.StandAloneSig, RawRowEqualityComparer.Instance); - public readonly MDTable EventMapTable = new MDTable(Table.EventMap, RawRowEqualityComparer.Instance); - public readonly MDTable EventPtrTable = new MDTable(Table.EventPtr, RawRowEqualityComparer.Instance); - public readonly MDTable EventTable = new MDTable(Table.Event, RawRowEqualityComparer.Instance); - public readonly MDTable PropertyMapTable = new MDTable(Table.PropertyMap, RawRowEqualityComparer.Instance); - public readonly MDTable PropertyPtrTable = new MDTable(Table.PropertyPtr, RawRowEqualityComparer.Instance); - public readonly MDTable PropertyTable = new MDTable(Table.Property, RawRowEqualityComparer.Instance); - public readonly MDTable MethodSemanticsTable = new MDTable(Table.MethodSemantics, RawRowEqualityComparer.Instance); - public readonly MDTable MethodImplTable = new MDTable(Table.MethodImpl, RawRowEqualityComparer.Instance); - public readonly MDTable ModuleRefTable = new MDTable(Table.ModuleRef, RawRowEqualityComparer.Instance); - public readonly MDTable TypeSpecTable = new MDTable(Table.TypeSpec, RawRowEqualityComparer.Instance); - public readonly MDTable ImplMapTable = new MDTable(Table.ImplMap, RawRowEqualityComparer.Instance); - public readonly MDTable FieldRVATable = new MDTable(Table.FieldRVA, RawRowEqualityComparer.Instance); - public readonly MDTable ENCLogTable = new MDTable(Table.ENCLog, RawRowEqualityComparer.Instance); - public readonly MDTable ENCMapTable = new MDTable(Table.ENCMap, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyTable = new MDTable(Table.Assembly, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyProcessorTable = new MDTable(Table.AssemblyProcessor, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyOSTable = new MDTable(Table.AssemblyOS, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyRefTable = new MDTable(Table.AssemblyRef, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyRefProcessorTable = new MDTable(Table.AssemblyRefProcessor, RawRowEqualityComparer.Instance); - public readonly MDTable AssemblyRefOSTable = new MDTable(Table.AssemblyRefOS, RawRowEqualityComparer.Instance); - public readonly MDTable FileTable = new MDTable(Table.File, RawRowEqualityComparer.Instance); - public readonly MDTable ExportedTypeTable = new MDTable(Table.ExportedType, RawRowEqualityComparer.Instance); - public readonly MDTable ManifestResourceTable = new MDTable(Table.ManifestResource, RawRowEqualityComparer.Instance); - public readonly MDTable NestedClassTable = new MDTable(Table.NestedClass, RawRowEqualityComparer.Instance); - 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 - - /// - /// All tables - /// - public readonly IMDTable[] Tables; - - /// - public string Name => IsENC ? "#-" : "#~"; - - /// - public bool IsEmpty => false; - - /// - /// true if the Edit 'N Continue name will be used (#-) - /// - public bool IsENC { - get { - if (options.UseENC.HasValue) - return options.UseENC.Value; - return hasDeletedRows || - !FieldPtrTable.IsEmpty || - !MethodPtrTable.IsEmpty || - !ParamPtrTable.IsEmpty || - !EventPtrTable.IsEmpty || - !PropertyPtrTable.IsEmpty || - !(InterfaceImplTable.IsEmpty || InterfaceImplTable.IsSorted) || - !(ConstantTable.IsEmpty || ConstantTable.IsSorted) || - !(CustomAttributeTable.IsEmpty || CustomAttributeTable.IsSorted) || - !(FieldMarshalTable.IsEmpty || FieldMarshalTable.IsSorted) || - !(DeclSecurityTable.IsEmpty || DeclSecurityTable.IsSorted) || - !(ClassLayoutTable.IsEmpty || ClassLayoutTable.IsSorted) || - !(FieldLayoutTable.IsEmpty || FieldLayoutTable.IsSorted) || - !(EventMapTable.IsEmpty || EventMapTable.IsSorted) || - !(PropertyMapTable.IsEmpty || PropertyMapTable.IsSorted) || - !(MethodSemanticsTable.IsEmpty || MethodSemanticsTable.IsSorted) || - !(MethodImplTable.IsEmpty || MethodImplTable.IsSorted) || - !(ImplMapTable.IsEmpty || ImplMapTable.IsSorted) || - !(FieldRVATable.IsEmpty || FieldRVATable.IsSorted) || - !(NestedClassTable.IsEmpty || NestedClassTable.IsSorted) || - !(GenericParamTable.IsEmpty || GenericParamTable.IsSorted) || - !(GenericParamConstraintTable.IsEmpty || GenericParamConstraintTable.IsSorted); - } - } - - /// - /// true if any rows have been deleted (eg. a deleted TypeDef, Method, Field, etc. - /// Its name has been renamed to _Deleted). - /// - public bool HasDeletedRows { - get => hasDeletedRows; - set => hasDeletedRows = value; - } - - /// - /// true if #Strings heap size > 0xFFFF - /// - public bool BigStrings { - get => bigStrings; - set => bigStrings = value; - } - - /// - /// true if #GUID heap size > 0xFFFF - /// - public bool BigGuid { - get => bigGuid; - set => bigGuid = value; - } - - /// - /// true if #Blob heap size > 0xFFFF - /// - public bool BigBlob { - get => bigBlob; - set => bigBlob = value; - } - - /// - /// Constructor - /// - /// Metadata owner - /// Options - public TablesHeap(Metadata metadata, TablesHeapOptions options) { - this.metadata = metadata; - this.options = options ?? new TablesHeapOptions(); - hasDeletedRows = this.options.HasDeletedRows ?? false; - Tables = new IMDTable[] { - ModuleTable, - TypeRefTable, - TypeDefTable, - FieldPtrTable, - FieldTable, - MethodPtrTable, - MethodTable, - ParamPtrTable, - ParamTable, - InterfaceImplTable, - MemberRefTable, - ConstantTable, - CustomAttributeTable, - FieldMarshalTable, - DeclSecurityTable, - ClassLayoutTable, - FieldLayoutTable, - StandAloneSigTable, - EventMapTable, - EventPtrTable, - EventTable, - PropertyMapTable, - PropertyPtrTable, - PropertyTable, - MethodSemanticsTable, - MethodImplTable, - ModuleRefTable, - TypeSpecTable, - ImplMapTable, - FieldRVATable, - ENCLogTable, - ENCMapTable, - AssemblyTable, - AssemblyProcessorTable, - AssemblyOSTable, - AssemblyRefTable, - AssemblyRefProcessorTable, - AssemblyRefOSTable, - FileTable, - ExportedTypeTable, - ManifestResourceTable, - NestedClassTable, - 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, - }; - } - - struct RawDummyRow { - 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 void SetReadOnly() { - foreach (var mdt in Tables) - mdt.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 - } - - /// - public uint GetFileLength() { - if (length == 0) - CalculateLength(); - return Utils.AlignUp(length, HeapBase.ALIGNMENT); - } - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - /// Calculates the length. This will set all MD tables to read-only. - /// - public void CalculateLength() { - if (length != 0) - return; - SetReadOnly(); - - majorVersion = options.MajorVersion ?? 2; - minorVersion = options.MinorVersion ?? 0; - - if (((majorVersion << 8) | minorVersion) <= 0x100) { - if (!GenericParamTable.IsEmpty || !MethodSpecTable.IsEmpty || !GenericParamConstraintTable.IsEmpty) - throw new ModuleWriterException("Tables heap version <= v1.0 but generic tables are not empty"); - } - - var dnTableSizes = new DotNetTableSizes(); - var tableInfos = dnTableSizes.CreateTables(majorVersion, minorVersion); - var rowCounts = GetRowCounts(); - - 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]; - - length = 24; - foreach (var mdt in Tables) { - if (mdt.IsEmpty) - continue; - length += (uint)(4 + mdt.TableInfo.RowSize * mdt.Rows); - } - if (options.ExtraData.HasValue) - length += 4; - } - - uint[] GetRowCounts() { - var sizes = new uint[Tables.Length]; - for (int i = 0; i < sizes.Length; i++) - sizes[i] = (uint)Tables[i].Rows; - 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; - - private void WriteTo0(DataWriter writer) { - 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.WriteInt32(mdt.Rows); - } - if (options.ExtraData.HasValue) - writer.WriteUInt32(options.ExtraData.Value); - - 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.WriteZeroes((int)(Utils.AlignUp(length, HeapBase.ALIGNMENT) - length)); - } - - /// - public void WriteTo(DataWriter writer) { - EncryptionUtil.WriteWithEncIfNeed(writer, WriteTo0, e => e.TableEnc, EncryptionContext.BigSegmentSize); - } - - MDStreamFlags GetMDStreamFlags() { - MDStreamFlags flags = 0; - if (bigStrings) - flags |= MDStreamFlags.BigStrings; - if (bigGuid) - flags |= MDStreamFlags.BigGUID; - if (bigBlob) - flags |= MDStreamFlags.BigBlob; - if (options.ExtraData.HasValue) - flags |= MDStreamFlags.ExtraData; - if (hasDeletedRows) - flags |= MDStreamFlags.HasDelete; - return flags; - } - - byte GetLog2Rid() { - //TODO: Sometimes this is 16. Probably when at least one of the table indexes requires 4 bytes. - return options.Log2Rid ?? 1; - } - - ulong GetValidMask() { - ulong mask = 0; - foreach (var mdt in Tables) { - if (!mdt.IsEmpty) - mask |= 1UL << (int)mdt.Table; - } - return mask; - } - - ulong GetSortedMask() { - ulong mask = 0; - foreach (var mdt in Tables) { - if (mdt.IsSorted) - mask |= 1UL << (int)mdt.Table; - } - return mask; - } - - /// - public override string ToString() => Name; - } -} diff --git a/Plugins/dnlib/DotNet/Writer/USHeap.cs b/Plugins/dnlib/DotNet/Writer/USHeap.cs deleted file mode 100644 index 8aff001..0000000 --- a/Plugins/dnlib/DotNet/Writer/USHeap.cs +++ /dev/null @@ -1,170 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using dnlib.IO; -using dnlib.DotNet.MD; -using dnlib.Protection; -using dnlib.Utils; - -namespace dnlib.DotNet.Writer { - /// - /// #US heap - /// - public sealed class USHeap : HeapBase, IOffsetHeap { - readonly Dictionary cachedDict = new Dictionary(StringComparer.Ordinal); - readonly List cached = new List(); - uint nextOffset = 1; - byte[] originalData; - Dictionary userRawData; - - /// - public override string Name => "#US"; - - /// - /// Populates strings from an existing (eg. to preserve - /// string tokens) - /// - /// The #US stream with the original content - public void Populate(USStream usStream) { - if (originalData is not null) - throw new InvalidOperationException("Can't call method twice"); - if (nextOffset != 1) - throw new InvalidOperationException("Add() has already been called"); - if (usStream is null || usStream.StreamLength == 0) - return; - - var reader = usStream.CreateReader(); - originalData = reader.ToArray(); - nextOffset = (uint)originalData.Length; - Populate(ref reader); - } - - void Populate(ref DataReader reader) { - reader.Position = 1; - while (reader.Position < reader.Length) { - uint offset = (uint)reader.Position; - if (!reader.TryReadCompressedUInt32(out uint len)) { - if (offset == reader.Position) - reader.Position++; - continue; - } - if (len == 0 || (ulong)reader.Position + len > reader.Length) - continue; - - int stringLen = (int)len / 2; - var s = reader.ReadUtf16String(stringLen); - if ((len & 1) != 0) - reader.ReadByte(); - - if (!cachedDict.ContainsKey(s)) - cachedDict[s] = offset; - } - } - - /// - /// Adds a string to the #US heap - /// - /// The string - /// The offset of the string in the #US heap - public uint Add(string s) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #US when it's read-only"); - if (s is null) - s = string.Empty; - - if (cachedDict.TryGetValue(s, out uint offset)) - return offset; - return AddToCache(s); - } - - /// - /// Adds a string to the #US heap - /// - /// The string - /// The offset of the string in the #US heap - public uint Create(string s) { - if (isReadOnly) - throw new ModuleWriterException("Trying to modify #US when it's read-only"); - return AddToCache(s ?? string.Empty); - } - - uint AddToCache(string s) { - uint offset; - cached.Add(s); - cachedDict[s] = offset = nextOffset; - nextOffset += (uint)GetRawDataSize(s); - if (offset > 0x00FFFFFF) - throw new ModuleWriterException("#US heap is too big"); - return offset; - } - - /// - public override uint GetRawLength() => nextOffset; - - protected override EncryptionMethod GetEncryptionMethod(IEncryption e) => e.UserStringEnc; - - /// - protected override void WriteToImpl(DataWriter writer) { - if (originalData is not null) - writer.WriteBytes(originalData); - else - writer.WriteByte(0); - - uint offset = originalData is not null ? (uint)originalData.Length : 1; - foreach (var s in cached) { - int rawLen = GetRawDataSize(s); - 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); - } - else - WriteString(writer, s); - offset += (uint)rawLen; - } - } - - void WriteStringContent(DataWriter writer, string s) { - byte last = 0; - for (int i = 0; i < s.Length; i++) { - ushort c = (ushort)s[i]; - writer.WriteUInt16(c); - if (c > 0xFF || (1 <= c && c <= 8) || (0x0E <= c && c <= 0x1F) || c == 0x27 || c == 0x2D || c == 0x7F) - last = 1; - } - writer.WriteByte(last); - } - - void WriteString(DataWriter writer, string s) { - //EncryptionUtil.WriteWitchEncIfNeed(writer, writer => WriteString0(writer, s), e => e.LazyUserStringEnc, EncryptionContext.SmallSegmentSize); - writer.WriteCompressedUInt32((uint)s.Length * 2 + 1); - EncryptionUtil.WriteWithEncIfNeed(writer, w => WriteStringContent(w, s), e => e.LazyUserStringEnc, EncryptionContext.SmallSegmentSize); - } - - /// - public int GetRawDataSize(string data) => DataWriter.GetCompressedUInt32Length((uint)data.Length * 2 + 1) + data.Length * 2 + 1; - - /// - public void SetRawData(uint offset, byte[] rawData) { - if (userRawData is null) - userRawData = new Dictionary(); - userRawData[offset] = rawData ?? throw new ArgumentNullException(nameof(rawData)); - } - - /// - public IEnumerable> GetAllRawData() { - var memStream = new MemoryStream(); - var writer = new DataWriter(memStream); - uint offset = originalData is not null ? (uint)originalData.Length : 1; - foreach (var s in cached) { - memStream.Position = 0; - memStream.SetLength(0); - WriteString(writer, s); - yield return new KeyValuePair(offset, memStream.ToArray()); - offset += (uint)memStream.Length; - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/UniqueChunkList.cs b/Plugins/dnlib/DotNet/Writer/UniqueChunkList.cs deleted file mode 100644 index 225bf80..0000000 --- a/Plugins/dnlib/DotNet/Writer/UniqueChunkList.cs +++ /dev/null @@ -1,82 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.DotNet.Writer { - /// - /// Re-uses existing chunks to save space - /// - /// Chunk type - public sealed class UniqueChunkList : ChunkListBase where T : class, IChunk { - Dictionary dict; - - /// - /// Default constructor - /// - public UniqueChunkList() - : this(EqualityComparer.Default) { - } - - /// - /// Constructor - /// - /// Compares the chunk type - public UniqueChunkList(IEqualityComparer chunkComparer) { - chunks = new List(); - dict = new Dictionary(new ElemEqualityComparer(chunkComparer)); - } - - /// - public override void SetOffset(FileOffset offset, RVA rva) { - dict = null; - base.SetOffset(offset, rva); - } - - /// - /// Adds a if not already present - /// - /// The chunk to add or null if none - /// Chunk alignment - /// The original input if it wasn't present, or the cached one - public T Add(T chunk, uint alignment) { - if (setOffsetCalled) - throw new InvalidOperationException("SetOffset() has already been called"); - if (chunk is null) - return null; - var elem = new Elem(chunk, alignment); - if (dict.TryGetValue(elem, out var other)) - return other.chunk; - dict[elem] = elem; - chunks.Add(elem); - return elem.chunk; - } - - /// - public override uint CalculateAlignment() { - uint alignment = base.CalculateAlignment(); - - 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; - } - - 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); - } - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/Win32ResourcesChunk.cs b/Plugins/dnlib/DotNet/Writer/Win32ResourcesChunk.cs deleted file mode 100644 index cf75e81..0000000 --- a/Plugins/dnlib/DotNet/Writer/Win32ResourcesChunk.cs +++ /dev/null @@ -1,478 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using dnlib.IO; -using dnlib.PE; -using dnlib.W32Resources; - -namespace dnlib.DotNet.Writer { - /// - /// Writes Win32 resources - /// - public sealed class Win32ResourcesChunk : IReuseChunk { - readonly Win32Resources win32Resources; - FileOffset offset; - RVA rva; - uint length; - readonly Dictionary dirDict = new Dictionary(); - readonly List dirList = new List(); - readonly Dictionary dataHeaderDict = new Dictionary(); - readonly List dataHeaderList = new List(); - readonly Dictionary stringsDict = new Dictionary(StringComparer.Ordinal); - readonly List stringsList = new List(); - readonly Dictionary dataDict = new Dictionary(); - readonly List dataList = new List(); - - /// - public FileOffset FileOffset => offset; - - /// - public RVA RVA => rva; - - /// - /// Constructor - /// - /// Win32 resources - public Win32ResourcesChunk(Win32Resources win32Resources) => this.win32Resources = win32Resources; - - /// - /// Returns the and of a - /// . must have been called. - /// - /// A - /// Updated with the file offset - /// Updated with the RVA - /// true if is valid and - /// and have been updated. false - /// if is not part of the Win32 resources. - public bool GetFileOffsetAndRvaOf(ResourceDirectoryEntry dirEntry, out FileOffset fileOffset, out RVA rva) { - if (dirEntry is ResourceDirectory dir) - return GetFileOffsetAndRvaOf(dir, out fileOffset, out rva); - - if (dirEntry is ResourceData dataHeader) - return GetFileOffsetAndRvaOf(dataHeader, out fileOffset, out rva); - - fileOffset = 0; - rva = 0; - return false; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The file offset or 0 if is invalid - public FileOffset GetFileOffset(ResourceDirectoryEntry dirEntry) { - GetFileOffsetAndRvaOf(dirEntry, out var fileOffset, out var rva); - return fileOffset; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The RVA or 0 if is invalid - public RVA GetRVA(ResourceDirectoryEntry dirEntry) { - GetFileOffsetAndRvaOf(dirEntry, out var fileOffset, out var rva); - return rva; - } - - /// - /// Returns the and of a - /// . must have been called. - /// - /// A - /// Updated with the file offset - /// Updated with the RVA - /// true if is valid and - /// 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 is null || !dirDict.TryGetValue(dir, out uint offs)) { - fileOffset = 0; - rva = 0; - return false; - } - - fileOffset = offset + offs; - rva = this.rva + offs; - return true; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The file offset or 0 if is invalid - public FileOffset GetFileOffset(ResourceDirectory dir) { - GetFileOffsetAndRvaOf(dir, out var fileOffset, out var rva); - return fileOffset; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The RVA or 0 if is invalid - public RVA GetRVA(ResourceDirectory dir) { - GetFileOffsetAndRvaOf(dir, out var fileOffset, out var rva); - return rva; - } - - /// - /// Returns the and of a - /// . must have been called. - /// - /// A - /// Updated with the file offset - /// Updated with the RVA - /// true if is valid and - /// 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 is null || !dataHeaderDict.TryGetValue(dataHeader, out uint offs)) { - fileOffset = 0; - rva = 0; - return false; - } - - fileOffset = offset + offs; - rva = this.rva + offs; - return true; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The file offset or 0 if is invalid - public FileOffset GetFileOffset(ResourceData dataHeader) { - GetFileOffsetAndRvaOf(dataHeader, out var fileOffset, out var rva); - return fileOffset; - } - - /// - /// Returns the of a . - /// must have been called. - /// - /// A - /// The RVA or 0 if is invalid - public RVA GetRVA(ResourceData dataHeader) { - GetFileOffsetAndRvaOf(dataHeader, out var fileOffset, out var rva); - return rva; - } - - /// - /// Returns the and of a - /// 's name. must have been - /// called. - /// - /// The name of a - /// Updated with the file offset - /// Updated with the RVA - /// true if is valid and - /// 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 is null || !stringsDict.TryGetValue(name, out uint offs)) { - fileOffset = 0; - rva = 0; - return false; - } - - fileOffset = offset + offs; - rva = this.rva + offs; - return true; - } - - /// - /// Returns the of a 's name. - /// must have been called. - /// - /// The name of a - /// The file offset or 0 if is invalid - public FileOffset GetFileOffset(string name) { - GetFileOffsetAndRvaOf(name, out var fileOffset, out var rva); - return fileOffset; - } - - /// - /// Returns the of a 's name. - /// must have been called. - /// - /// The name of a - /// The RVA or 0 if is invalid - public RVA GetRVA(string name) { - GetFileOffsetAndRvaOf(name, out var fileOffset, out var rva); - return rva; - } - - const uint RESOURCE_DIR_ALIGNMENT = 4; - const uint RESOURCE_DATA_HEADER_ALIGNMENT = 4; - const uint RESOURCE_STRING_ALIGNMENT = 2; - const uint RESOURCE_DATA_ALIGNMENT = 4; - - bool IReuseChunk.CanReuse(RVA origRva, 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 is 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 is 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: - // 1. All resource directories. The root is always first. - // 2. All resource data headers. - // 3. All the strings. - // 4. All resource data. - - uint rsrcOffset = 0; - var maxAlignment = GetMaxAlignment(offset, out var error); - if (error is not null) - throw new ModuleWriterException(error); - - foreach (var dir in dirList) { - rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_DIR_ALIGNMENT); - dirDict[dir] = rsrcOffset; - if (dir != dirList[0]) - AddString(dir.Name); - rsrcOffset += 16 + (uint)(dir.Directories.Count + dir.Data.Count) * 8; - } - - foreach (var data in dataHeaderList) { - rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_DATA_HEADER_ALIGNMENT); - dataHeaderDict[data] = rsrcOffset; - AddString(data.Name); - AddData(data); - rsrcOffset += 16; - } - - foreach (var s in stringsList) { - rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_STRING_ALIGNMENT); - stringsDict[s] = rsrcOffset; - rsrcOffset += 2 + (uint)(s.Length * 2); - } - - foreach (var data in dataList) { - rsrcOffset = Utils.AlignUp(rsrcOffset, RESOURCE_DATA_ALIGNMENT); - dataDict[data] = rsrcOffset; - rsrcOffset += data.CreateReader().Length; - } - - length = rsrcOffset; - } - - void AddData(ResourceData data) { - if (dataDict.ContainsKey(data)) - return; - dataList.Add(data); - dataDict.Add(data, 0); - } - - void AddString(ResourceName name) { - if (!name.HasName || stringsDict.ContainsKey(name.Name)) - return; - stringsList.Add(name.Name); - stringsDict.Add(name.Name, 0); - } - - void FindDirectoryEntries() => FindDirectoryEntries(win32Resources.Root); - - void FindDirectoryEntries(ResourceDirectory dir) { - if (dirDict.ContainsKey(dir)) - return; - dirList.Add(dir); - dirDict[dir] = 0; - 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); - dataHeaderDict[data] = 0; - } - } - - /// - public uint GetFileLength() => length; - - /// - public uint GetVirtualSize() => GetFileLength(); - - /// - public uint CalculateAlignment() => 0; - - /// - public void WriteTo(DataWriter writer) { - uint offset = 0; - - // The order here must be the same as in SetOffset() - - foreach (var dir in dirList) { - uint padding = Utils.AlignUp(offset, RESOURCE_DIR_ALIGNMENT) - offset; - writer.WriteZeroes((int)padding); - offset += padding; - if (dirDict[dir] != offset) - throw new ModuleWriterException("Invalid Win32 resource directory offset"); - offset += WriteTo(writer, dir); - } - - foreach (var dataHeader in dataHeaderList) { - uint padding = Utils.AlignUp(offset, RESOURCE_DATA_HEADER_ALIGNMENT) - offset; - writer.WriteZeroes((int)padding); - offset += padding; - if (dataHeaderDict[dataHeader] != offset) - throw new ModuleWriterException("Invalid Win32 resource data header offset"); - offset += WriteTo(writer, dataHeader); - } - - foreach (var s in stringsList) { - uint padding = Utils.AlignUp(offset, RESOURCE_STRING_ALIGNMENT) - offset; - writer.WriteZeroes((int)padding); - offset += padding; - if (stringsDict[s] != offset) - throw new ModuleWriterException("Invalid Win32 resource string offset"); - - var bytes = Encoding.Unicode.GetBytes(s); - if (bytes.Length / 2 > ushort.MaxValue) - throw new ModuleWriterException("Win32 resource entry name is too long"); - writer.WriteUInt16((ushort)(bytes.Length / 2)); - writer.WriteBytes(bytes); - offset += 2 + (uint)bytes.Length; - } - - var dataBuffer = new byte[0x2000]; - foreach (var data in dataList) { - uint padding = Utils.AlignUp(offset, RESOURCE_DATA_ALIGNMENT) - offset; - writer.WriteZeroes((int)padding); - offset += padding; - if (dataDict[data] != offset) - throw new ModuleWriterException("Invalid Win32 resource data offset"); - - var reader = data.CreateReader(); - offset += reader.BytesLeft; - reader.CopyTo(writer, dataBuffer); - } - } - - uint WriteTo(DataWriter writer, ResourceDirectory dir) { - 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.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.WriteUInt32(0x80000000 | stringsDict[d.Name.Name]); - writer.WriteUInt32(GetDirectoryEntryOffset(d)); - } - - foreach (var d in ids) { - writer.WriteInt32(d.Name.Id); - writer.WriteUInt32(GetDirectoryEntryOffset(d)); - } - - return 16 + (uint)(named.Count + ids.Count) * 8; - } - - uint GetDirectoryEntryOffset(ResourceDirectoryEntry e) { - if (e is ResourceData) - return dataHeaderDict[(ResourceData)e]; - return 0x80000000 | dirDict[(ResourceDirectory)e]; - } - - static void GetNamedAndIds(ResourceDirectory dir, out List named, out List ids) { - named = new List(); - ids = new List(); - 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); - } - 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 - named.Add(d); - } - } - - uint WriteTo(DataWriter writer, ResourceData dataHeader) { - writer.WriteUInt32((uint)rva + dataDict[dataHeader]); - writer.WriteUInt32((uint)dataHeader.CreateReader().Length); - writer.WriteUInt32(dataHeader.CodePage); - writer.WriteUInt32(dataHeader.Reserved); - return 16; - } - } -} diff --git a/Plugins/dnlib/DotNet/Writer/WriterUtils.cs b/Plugins/dnlib/DotNet/Writer/WriterUtils.cs deleted file mode 100644 index 52ea2cf..0000000 --- a/Plugins/dnlib/DotNet/Writer/WriterUtils.cs +++ /dev/null @@ -1,37 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.DotNet.Writer { - static class WriterUtils { - public static uint WriteCompressedUInt32(this DataWriter writer, IWriterError helper, uint value) { - if (value > 0x1FFFFFFF) { - helper.Error("UInt32 value is too big and can't be compressed"); - value = 0x1FFFFFFF; - } - writer.WriteCompressedUInt32(value); - return 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; - } - else if (value > 0x0FFFFFFF) { - helper.Error("Int32 value is too big and can't be compressed."); - value = 0x0FFFFFFF; - } - writer.WriteCompressedInt32(value); - return value; - } - - public static void Write(this DataWriter writer, IWriterError helper, UTF8String s) { - if (UTF8String.IsNull(s)) { - helper.Error("UTF8String is null"); - s = UTF8String.Empty; - } - - writer.WriteCompressedUInt32(helper, (uint)s.DataLength); - writer.WriteBytes(s.Data); - } - } -} diff --git a/Plugins/dnlib/HandleProcessCorruptedStateExceptionsAttribute.cs b/Plugins/dnlib/HandleProcessCorruptedStateExceptionsAttribute.cs deleted file mode 100644 index a1cdf67..0000000 --- a/Plugins/dnlib/HandleProcessCorruptedStateExceptionsAttribute.cs +++ /dev/null @@ -1,9 +0,0 @@ -// 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/Plugins/dnlib/IO/AlignedByteArrayDataStream.cs b/Plugins/dnlib/IO/AlignedByteArrayDataStream.cs deleted file mode 100644 index bad123a..0000000 --- a/Plugins/dnlib/IO/AlignedByteArrayDataStream.cs +++ /dev/null @@ -1,108 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace dnlib.IO { - sealed unsafe class AlignedByteArrayDataStream : DataStream { - readonly byte[] data; - - public AlignedByteArrayDataStream(byte[] data) => this.data = data; - - public override void ReadBytes(uint offset, void* destination, int length) => - Marshal.Copy(data, (int)offset, (IntPtr)destination, length); - - public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => - Array.Copy(data, (int)offset, destination, destinationIndex, length); - - public override byte ReadByte(uint offset) => data[(int)offset]; - - public override ushort ReadUInt16(uint offset) { - int i = (int)offset; - var data = this.data; - return (ushort)(data[i++] | (data[i] << 8)); - } - - 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 ulong ReadUInt64(uint offset) { - int i = (int)offset; - var data = this.data; - return 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 float ReadSingle(uint offset) { - int i = (int)offset; - var data = this.data; - uint value = data[i++] | ((uint)data[i++] << 8) | ((uint)data[i++] << 16) | ((uint)data[i] << 24); - return *(float*)&value; - } - - public override double ReadDouble(uint offset) { - int i = (int)offset; - var data = this.data; - ulong value = 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); - return *(double*)&value; - } - - public override string ReadUtf16String(uint offset, int chars) { - fixed (byte* p = data) - return new string((char*)(p + offset), 0, chars); - } - - public override string ReadString(uint offset, int length, Encoding encoding) { - fixed (byte* p = data) - return new string((sbyte*)(p + offset), 0, length, encoding); - } - - public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) { - fixed (byte* pd = data) { - // If this code gets updated, also update the other DataStream implementations - - byte* p = pd + offset; - - uint count = (endOffset - offset) / 4; - for (uint i = 0; i < count; i++) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - - byte* pe = pd + endOffset; - while (p != pe) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - valueOffset = 0; - return false; - } - } - } -} diff --git a/Plugins/dnlib/IO/AlignedNativeMemoryDataStream.cs b/Plugins/dnlib/IO/AlignedNativeMemoryDataStream.cs deleted file mode 100644 index 6f9392c..0000000 --- a/Plugins/dnlib/IO/AlignedNativeMemoryDataStream.cs +++ /dev/null @@ -1,119 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace dnlib.IO { - sealed unsafe class AlignedNativeMemoryDataStream : DataStream { - readonly byte* data; - - public AlignedNativeMemoryDataStream(byte* data) => this.data = data; - - public override void ReadBytes(uint offset, void* destination, int length) { - var ps = data + offset; - var pd = (byte*)destination; - int count = length / 4; - length = length % 4; - for (int i = 0; i < count; i++) { - *pd = *ps; - pd++; - ps++; - - *pd = *ps; - pd++; - ps++; - - *pd = *ps; - pd++; - ps++; - - *pd = *ps; - pd++; - ps++; - } - for (int i = 0; i < length; i++, ps++, pd++) - *pd = *ps; - } - - public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => - Marshal.Copy((IntPtr)(data + offset), destination, destinationIndex, length); - - public override byte ReadByte(uint offset) => *(data + offset); - - public override ushort ReadUInt16(uint offset) { - var p = data + offset; - return (ushort)(*p++ | (*p << 8)); - } - - public override uint ReadUInt32(uint offset) { - var p = data + offset; - return *p++ | ((uint)*p++ << 8) | ((uint)*p++ << 16) | ((uint)*p << 24); - } - - public override ulong ReadUInt64(uint offset) { - var p = data + offset; - return *p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) | - ((ulong)*p++ << 32) | ((ulong)*p++ << 40) | ((ulong)*p++ << 48) | ((ulong)*p << 56); - } - - public override float ReadSingle(uint offset) { - var p = data + offset; - uint value = *p++ | ((uint)*p++ << 8) | ((uint)*p++ << 16) | ((uint)*p << 24); - return *(float*)&value; - } - - public override double ReadDouble(uint offset) { - var p = data + offset; - ulong value = *p++ | ((ulong)*p++ << 8) | ((ulong)*p++ << 16) | ((ulong)*p++ << 24) | - ((ulong)*p++ << 32) | ((ulong)*p++ << 40) | ((ulong)*p++ << 48) | ((ulong)*p << 56); - return *(double*)&value; - } - - public override string ReadUtf16String(uint offset, int chars) => new string((char*)(data + offset), 0, chars); - public override string ReadString(uint offset, int length, Encoding encoding) => new string((sbyte*)(data + offset), 0, length, encoding); - - public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) { - var pd = data; - - // If this code gets updated, also update the other DataStream implementations - - byte* p = pd + offset; - - uint count = (endOffset - offset) / 4; - for (uint i = 0; i < count; i++) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - - byte* pe = pd + endOffset; - while (p != pe) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - valueOffset = 0; - return false; - } - } -} diff --git a/Plugins/dnlib/IO/ByteArrayDataReaderFactory.cs b/Plugins/dnlib/IO/ByteArrayDataReaderFactory.cs deleted file mode 100644 index 323d1ba..0000000 --- a/Plugins/dnlib/IO/ByteArrayDataReaderFactory.cs +++ /dev/null @@ -1,72 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.IO { - /// - /// A that reads from a byte array - /// - public sealed class ByteArrayDataReaderFactory : DataReaderFactory { - /// - /// The filename or null if the data is not from a file - /// - public override string Filename => filename; - - /// - /// Gets the total length of the data - /// - public override uint Length => length; - - internal byte[] DataArray => data; - internal uint DataOffset => 0; - - DataStream stream; - string filename; - uint length; - byte[] data; - - ByteArrayDataReaderFactory(byte[] data, string filename) { - this.filename = filename; - length = (uint)data.Length; - stream = DataStreamFactory.Create(data); - this.data = data; - } - - /// - /// Creates a instance - /// - /// Data - /// The filename or null if the data is not from a file - /// - public static ByteArrayDataReaderFactory Create(byte[] data, string filename) { - if (data is null) - throw new ArgumentNullException(nameof(data)); - return new ByteArrayDataReaderFactory(data, filename); - } - - /// - /// Creates a data reader - /// - /// Data - /// - public static DataReader CreateReader(byte[] data) => Create(data, filename: null).CreateReader(); - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public override DataReader CreateReader(uint offset, uint length) => CreateReader(stream, offset, length); - - /// - /// This method doesn't need to be called since a has nothing that must be cleaned up - /// - public override void Dispose() { - stream = EmptyDataStream.Instance; - length = 0; - filename = null; - data = null; - } - } -} diff --git a/Plugins/dnlib/IO/DataReader.cs b/Plugins/dnlib/IO/DataReader.cs deleted file mode 100644 index 84717d2..0000000 --- a/Plugins/dnlib/IO/DataReader.cs +++ /dev/null @@ -1,906 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.Serialization; -using System.Text; -using dnlib.DotNet.Writer; - -namespace dnlib.IO { - /// - /// Thrown by a when it can't read data or if the caller tries to set an invalid offset - /// - [Serializable] - public sealed class DataReaderException : IOException { - internal DataReaderException(string message) : base(message) { } - internal DataReaderException(SerializationInfo info, StreamingContext context) : base(info, context) { } - } - - /// - /// Reads data - /// - [DebuggerDisplay("{StartOffset,h}-{EndOffset,h} Length={Length} BytesLeft={BytesLeft}")] - public struct DataReader { - /// - /// Gets the start offset of the data - /// - public readonly uint StartOffset => startOffset; - - /// - /// Gets the end offset of the data, not inclusive - /// - public readonly uint EndOffset => endOffset; - - /// - /// Gets the total length of the data - /// - public readonly uint Length => endOffset - startOffset; - - /// - /// Gets the current offset. This is between and (inclusive) - /// - public uint CurrentOffset { - readonly get => currentOffset; - set { - VerifyState(); - if (value < startOffset || value > endOffset) { - // Invalid offsets should be an IOException and not an ArgumentException - ThrowDataReaderException($"Invalid new {nameof(CurrentOffset)}"); - } - currentOffset = value; - VerifyState(); - } - } - - /// - /// Gets/sets the position relative to - /// - public uint Position { - readonly get => currentOffset - startOffset; - set { - VerifyState(); - if (value > Length) { - // Invalid positions should be an IOException and not an ArgumentException - ThrowDataReaderException($"Invalid new {nameof(Position)}"); - } - currentOffset = startOffset + value; - VerifyState(); - } - } - - /// - /// Gets the number of bytes that can be read without throwing an exception - /// - public readonly uint BytesLeft => endOffset - currentOffset; - - readonly DataStream stream; - readonly uint startOffset; - readonly uint endOffset; - uint currentOffset; - - /// - /// Constructor - /// - /// Stream - /// Start offset of data - /// Length of data - public DataReader(DataStream stream, uint offset, uint length) { - Debug.Assert(stream is not null || (offset == 0 && length == 0)); - Debug.Assert(offset + length >= offset); - this.stream = stream; - startOffset = offset; - endOffset = offset + length; - currentOffset = offset; - VerifyState(); - } - - [Conditional("DEBUG")] - readonly void VerifyState() { - Debug.Assert(startOffset <= currentOffset); - Debug.Assert(currentOffset <= endOffset); - } - - 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 - /// - public void Reset() => currentOffset = startOffset; - - /// - /// Creates a new reader that can access a smaller part of this reader - /// - /// Start position relative to - /// Length of data - /// - public readonly DataReader Slice(uint start, uint length) { - if ((ulong)start + length > Length) - ThrowInvalidArgument(nameof(length)); - return new DataReader(stream, startOffset + start, length); - } - - /// - /// Creates a new reader that can access everything from to the end of the data - /// - /// Start position relative to - /// - public readonly DataReader Slice(uint start) { - if (start > Length) - ThrowInvalidArgument(nameof(start)); - return Slice(start, Length - start); - } - - /// - /// Creates a new reader that can access a smaller part of this reader - /// - /// Start position relative to - /// Length of data - /// - public readonly DataReader Slice(int start, int length) { - if (start < 0) - ThrowInvalidArgument(nameof(start)); - if (length < 0) - ThrowInvalidArgument(nameof(length)); - return Slice((uint)start, (uint)length); - } - - /// - /// Creates a new reader that can access everything from to the end of the data - /// - /// Start position relative to - /// - public readonly DataReader Slice(int start) { - if (start < 0) - ThrowInvalidArgument(nameof(start)); - if ((uint)start > Length) - ThrowInvalidArgument(nameof(start)); - return Slice((uint)start, Length - (uint)start); - } - - /// - /// Checks if it's possible to read bytes - /// - /// Length of data - /// - public readonly bool CanRead(int length) => length >= 0 && (uint)length <= BytesLeft; - - /// - /// Checks if it's possible to read bytes - /// - /// Length of data - /// - public readonly bool CanRead(uint length) => length <= BytesLeft; - - /// - /// Reads a - /// - /// - 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() { - 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 - /// - /// - 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 - /// - /// - public byte ReadByte() { - VerifyState(); - const uint SIZE = 1; - var currentOffset = this.currentOffset; - if (currentOffset == endOffset) - ThrowNoMoreBytesLeft(); - var value = stream.ReadByte(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// 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; - } - - /// - /// Reads a - /// - /// - public ushort ReadUInt16() { - VerifyState(); - const uint SIZE = 2; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadUInt16(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// 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; - } - - /// - /// Reads a - /// - /// - public uint ReadUInt32() { - VerifyState(); - const uint SIZE = 4; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadUInt32(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - internal byte Unsafe_ReadByte() { - VerifyState(); - const uint SIZE = 1; - var currentOffset = this.currentOffset; - Debug.Assert(currentOffset != endOffset); - var value = stream.ReadByte(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - internal ushort Unsafe_ReadUInt16() { - VerifyState(); - const uint SIZE = 2; - var currentOffset = this.currentOffset; - Debug.Assert(endOffset - currentOffset >= SIZE); - var value = stream.ReadUInt16(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - internal uint Unsafe_ReadUInt32() { - VerifyState(); - const uint SIZE = 4; - var currentOffset = this.currentOffset; - Debug.Assert(endOffset - currentOffset >= SIZE); - var value = stream.ReadUInt32(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// 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; - } - - /// - /// Reads a - /// - /// - public ulong ReadUInt64() { - VerifyState(); - const uint SIZE = 8; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadUInt64(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// Reads a - /// - /// - public float ReadSingle() { - VerifyState(); - const uint SIZE = 4; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadSingle(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// Reads a - /// - /// - public double ReadDouble() { - VerifyState(); - const uint SIZE = 8; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadDouble(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// Reads a - /// - /// - public Guid ReadGuid() { - VerifyState(); - const uint SIZE = 16; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < SIZE) - ThrowNoMoreBytesLeft(); - var value = stream.ReadGuid(currentOffset); - this.currentOffset = currentOffset + SIZE; - VerifyState(); - return value; - } - - /// - /// Reads a - /// - /// - public decimal ReadDecimal() { - 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; - } - - /// - /// Reads a UTF-16 encoded - /// - /// Number of characters to read - /// - public string ReadUtf16String(int chars) { - if (chars < 0) - ThrowInvalidArgument(nameof(chars)); - if (chars == 0) - return string.Empty; - VerifyState(); - uint length = (uint)chars * 2; - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < length) - ThrowNoMoreBytesLeft(); - var s = length == 0 ? string.Empty : stream.ReadUtf16String(currentOffset, chars); - this.currentOffset = currentOffset + length; - VerifyState(); - return s; - } - - /// - /// Reads bytes - /// - /// Destination pointer - /// Number of bytes to read - public unsafe void ReadBytes(void* destination, int length) { - if (destination is null && length != 0) - ThrowArgumentNullException(nameof(destination)); - if (length < 0) - ThrowInvalidArgument(nameof(length)); - // This is also true if 'this' is the 'default' instance ('stream' is null) - if (length == 0) - return; - VerifyState(); - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < (uint)length) - ThrowNoMoreBytesLeft(); - stream.ReadBytes(currentOffset, destination, length); - this.currentOffset = currentOffset + (uint)length; - VerifyState(); - } - - /// - /// Reads bytes - /// - /// Destination array - /// Destination index - /// Number of bytes to read - public void ReadBytes(byte[] destination, int destinationIndex, int length) { - if (destination is null) - ThrowArgumentNullException(nameof(destination)); - if (destinationIndex < 0) - ThrowInvalidArgument(nameof(destinationIndex)); - if (length < 0) - ThrowInvalidArgument(nameof(length)); - // This is also true if 'this' is the 'default' instance ('stream' is null) - if (length == 0) - return; - VerifyState(); - var currentOffset = this.currentOffset; - if (endOffset - currentOffset < (uint)length) - ThrowNoMoreBytesLeft(); - stream.ReadBytes(currentOffset, destination, destinationIndex, length); - this.currentOffset = currentOffset + (uint)length; - VerifyState(); - } - - /// - /// Reads bytes - /// - /// Number of bytes to read - /// - public byte[] ReadBytes(int length) { - if (length < 0) - ThrowInvalidArgument(nameof(length)); - if (length == 0) - return Array2.Empty(); - var data = new byte[length]; - ReadBytes(data, 0, length); - return data; - } - - /// - /// Reads a compressed - /// - /// Uncompressed - /// - public bool TryReadCompressedUInt32(out uint value) { - VerifyState(); - var currentOffset = this.currentOffset; - var bytesLeft = endOffset - currentOffset; - if (bytesLeft == 0) { - value = 0; - VerifyState(); - return false; - } - - var stream = this.stream; - byte b = stream.ReadByte(currentOffset++); - if ((b & 0x80) == 0) { - value = b; - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - if ((b & 0xC0) == 0x80) { - if (bytesLeft < 2) { - value = 0; - VerifyState(); - return false; - } - value = (uint)(((b & 0x3F) << 8) | stream.ReadByte(currentOffset++)); - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - // The encoding 111x isn't allowed but the CLR sometimes doesn't verify this - // and just assumes it's 110x. Don't fail if it's 111x, just assume it's 110x. - - if (bytesLeft < 4) { - value = 0; - VerifyState(); - return false; - } - value = (uint)(((b & 0x1F) << 24) | (stream.ReadByte(currentOffset++) << 16) | - (stream.ReadByte(currentOffset++) << 8) | stream.ReadByte(currentOffset++)); - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - /// - /// Reads a compressed - /// - /// - public uint ReadCompressedUInt32() { - if (!TryReadCompressedUInt32(out uint value)) - ThrowNoMoreBytesLeft(); - return value; - } - - /// - /// Reads a compressed - /// - /// Uncompressed - /// - public bool TryReadCompressedInt32(out int value) { - VerifyState(); - var currentOffset = this.currentOffset; - var bytesLeft = endOffset - currentOffset; - if (bytesLeft == 0) { - value = 0; - VerifyState(); - return false; - } - - var stream = this.stream; - byte b = stream.ReadByte(currentOffset++); - if ((b & 0x80) == 0) { - if ((b & 1) != 0) - value = -0x40 | (b >> 1); - else - value = (b >> 1); - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - if ((b & 0xC0) == 0x80) { - if (bytesLeft < 2) { - value = 0; - VerifyState(); - return false; - } - uint tmp = (uint)(((b & 0x3F) << 8) | stream.ReadByte(currentOffset++)); - if ((tmp & 1) != 0) - value = -0x2000 | (int)(tmp >> 1); - else - value = (int)(tmp >> 1); - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - if ((b & 0xE0) == 0xC0) { - if (bytesLeft < 4) { - value = 0; - VerifyState(); - return false; - } - uint tmp = (uint)(((b & 0x1F) << 24) | (stream.ReadByte(currentOffset++) << 16) | - (stream.ReadByte(currentOffset++) << 8) | stream.ReadByte(currentOffset++)); - if ((tmp & 1) != 0) - value = -0x10000000 | (int)(tmp >> 1); - else - value = (int)(tmp >> 1); - this.currentOffset = currentOffset; - VerifyState(); - return true; - } - - value = 0; - VerifyState(); - return false; - } - - /// - /// Reads a compressed - /// - /// - public int ReadCompressedInt32() { - if (!TryReadCompressedInt32(out int value)) - ThrowNoMoreBytesLeft(); - return value; - } - - /// - /// Reads a 7-bit encoded integer - /// - /// - public uint Read7BitEncodedUInt32() { - uint val = 0; - int bits = 0; - for (int i = 0; i < 5; i++) { - byte b = ReadByte(); - val |= (uint)(b & 0x7F) << bits; - if ((b & 0x80) == 0) - return val; - bits += 7; - } - ThrowDataReaderException("Invalid encoded UInt32"); - return 0; - } - - /// - /// Reads a 7-bit encoded integer - /// - /// - public int Read7BitEncodedInt32() => (int)Read7BitEncodedUInt32(); - - /// - /// Reads a serialized UTF-8 string - /// - /// - public string ReadSerializedString() => ReadSerializedString(Encoding.UTF8); - - /// - /// Reads a serialized string - /// - /// Encoding - /// - public string ReadSerializedString(Encoding encoding) { - if (encoding is null) - ThrowArgumentNullException(nameof(encoding)); - int length = Read7BitEncodedInt32(); - if (length < 0) - ThrowNoMoreBytesLeft(); - if (length == 0) - return string.Empty; - return ReadString(length, encoding); - } - - /// - /// Returns all data without updating the current position - /// - /// - public readonly byte[] ToArray() { - int length = (int)Length; - if (length < 0) - ThrowInvalidOperationException(); - // This is also true if 'this' is the 'default' instance ('stream' is null) - if (length == 0) - return Array2.Empty(); - var data = new byte[length]; - stream.ReadBytes(startOffset, data, 0, data.Length); - return data; - } - - /// - /// Returns the remaining data - /// - /// - public byte[] ReadRemainingBytes() { - int length = (int)BytesLeft; - if (length < 0) - ThrowInvalidOperationException(); - return ReadBytes(length); - } - - /// - /// Reads all bytes until a terminating byte or returns null if wasn't found. - /// If found, the current offset is incremented by the length of the returned data - /// - /// Terminating byte value - /// - public byte[] TryReadBytesUntil(byte value) { - var currentOffset = this.currentOffset; - var endOffset = this.endOffset; - // This is also true if 'this' is the 'default' instance ('stream' is null) - if (currentOffset == endOffset) - return null; - if (!stream.TryGetOffsetOf(currentOffset, endOffset, value, out var valueOffset)) - return null; - int length = (int)(valueOffset - currentOffset); - if (length < 0) - return null; - return ReadBytes(length); - } - - /// - /// 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. - /// - /// Encoding - /// - public string TryReadZeroTerminatedString(Encoding encoding) { - if (encoding is null) - ThrowArgumentNullException(nameof(encoding)); - VerifyState(); - var currentOffset = this.currentOffset; - var endOffset = this.endOffset; - // This is also true if 'this' is the 'default' instance ('stream' is null) - if (currentOffset == endOffset) - return null; - if (!stream.TryGetOffsetOf(currentOffset, endOffset, 0, out var valueOffset)) - return null; - int length = (int)(valueOffset - currentOffset); - if (length < 0) - return null; - var value = length == 0 ? string.Empty : stream.ReadString(currentOffset, length, encoding); - this.currentOffset = valueOffset + 1; - VerifyState(); - 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 - /// - /// Number of bytes to read (not characters) - /// Encoding - /// - public string ReadString(int byteCount, Encoding encoding) { - if (byteCount < 0) - ThrowInvalidArgument(nameof(byteCount)); - if (encoding is null) - ThrowArgumentNullException(nameof(encoding)); - if (byteCount == 0) - return string.Empty; - if ((uint)byteCount > Length) - ThrowInvalidArgument(nameof(byteCount)); - VerifyState(); - var currentOffset = this.currentOffset; - var value = stream.ReadString(currentOffset, byteCount, encoding); - this.currentOffset = currentOffset + (uint)byteCount; - VerifyState(); - return value; - } - - /// - /// Creates a that can access this content. The caller doesn't have to dispose of the returned stream. - /// - /// - public readonly Stream AsStream() => new DataReaderStream(this); - - readonly 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 is null) - ThrowArgumentNullException(nameof(destination)); - if (Position >= Length) - return; - 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 is null) - ThrowArgumentNullException(nameof(destination)); - CopyTo(destination.InternalStream, dataBuffer); - } - - /// - /// Copies the data, starting from , to - /// - /// Destination - /// Number of bytes written - public void CopyTo(BinaryWriter destination) { - if (destination is null) - ThrowArgumentNullException(nameof(destination)); - if (Position >= Length) - return; - CopyTo(destination.BaseStream, AllocTempBuffer()); - } - - /// - /// Copies the data, starting from , to - /// - /// Destination - /// Temp buffer during writing - /// Number of bytes written - public void CopyTo(BinaryWriter destination, byte[] dataBuffer) { - if (destination is null) - ThrowArgumentNullException(nameof(destination)); - CopyTo(destination.BaseStream, dataBuffer); - } - - /// - /// Copies the data, starting from , to - /// - /// Destination - /// Number of bytes written - public void CopyTo(Stream destination) { - if (destination is null) - ThrowArgumentNullException(nameof(destination)); - if (Position >= Length) - return; - CopyTo(destination, AllocTempBuffer()); - } - - /// - /// Copies the data, starting from , to - /// - /// Destination - /// Temp buffer during writing - /// Number of bytes written - public void CopyTo(Stream destination, byte[] dataBuffer) { - if (destination is null) - ThrowArgumentNullException(nameof(destination)); - if (dataBuffer is null) - 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); - lenLeft -= (uint)num; - ReadBytes(dataBuffer, 0, num); - destination.Write(dataBuffer, 0, num); - } - } - } -} diff --git a/Plugins/dnlib/IO/DataReaderFactory.cs b/Plugins/dnlib/IO/DataReaderFactory.cs deleted file mode 100644 index a224011..0000000 --- a/Plugins/dnlib/IO/DataReaderFactory.cs +++ /dev/null @@ -1,109 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; - -namespace dnlib.IO { - /// - /// Creates s that can read its data. - /// - /// This factory class is thread safe and its data can be read by on any thread. - /// - public abstract class DataReaderFactory : IDisposable { - /// - /// The filename or null if the data is not from a file - /// - public abstract string Filename { get; } - - /// - /// Gets the total length of the data - /// - public abstract uint Length { get; } - - /// - /// Creates a data reader that can read all data - /// - /// - public DataReader CreateReader() => CreateReader(0U, Length); - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public abstract DataReader CreateReader(uint offset, uint length); - - 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 - /// - /// Offset of data - /// Length of data - /// - public DataReader CreateReader(uint offset, int length) { - if (length < 0) - ThrowArgumentOutOfRangeException(nameof(length)); - return CreateReader(offset, (uint)length); - } - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public DataReader CreateReader(int offset, uint length) { - if (offset < 0) - ThrowArgumentOutOfRangeException(nameof(offset)); - return CreateReader((uint)offset, length); - } - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public DataReader CreateReader(int offset, int length) { - if (offset < 0 || length < 0) - Throw_CreateReader_2(offset, length); - return CreateReader((uint)offset, (uint)length); - } - - /// - /// Creates a data reader - /// - /// Stream - /// Offset of data - /// Length of data - /// - protected DataReader CreateReader(DataStream stream, uint offset, uint length) { - uint maxOffset = Length; - if (offset > maxOffset) - offset = maxOffset; - if ((ulong)offset + length > maxOffset) - length = maxOffset - offset; - return new DataReader(stream, offset, length); - } - - /// - /// Raised when all cached s created by this instance must be recreated - /// - public virtual event EventHandler DataReaderInvalidated { add { } remove { } } - - /// - /// Disposes of this instance - /// - public abstract void Dispose(); - } -} diff --git a/Plugins/dnlib/IO/DataReaderFactoryFactory.cs b/Plugins/dnlib/IO/DataReaderFactoryFactory.cs deleted file mode 100644 index 9a16dec..0000000 --- a/Plugins/dnlib/IO/DataReaderFactoryFactory.cs +++ /dev/null @@ -1,37 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace dnlib.IO { - static class DataReaderFactoryFactory { - static readonly bool isUnix; - - static DataReaderFactoryFactory() { - // See http://mono-project.com/FAQ:_Technical#Mono_Platforms for platform detection. - int p = (int)Environment.OSVersion.Platform; - if (p == 4 || p == 6 || p == 128) - isUnix = true; -#if NETSTANDARD || NETCOREAPP - if (!RuntimeInformation.IsOSPlatform(OSPlatform.Windows)) - isUnix = true; -#endif - } - - public static DataReaderFactory Create(string fileName, bool mapAsImage) { - var creator = CreateDataReaderFactory(fileName, mapAsImage); - if (creator is not null) - return creator; - - return ByteArrayDataReaderFactory.Create(File.ReadAllBytes(fileName), fileName); - } - - static DataReaderFactory CreateDataReaderFactory(string fileName, bool mapAsImage) { - if (!isUnix) - return MemoryMappedDataReaderFactory.CreateWindows(fileName, mapAsImage); - else - return MemoryMappedDataReaderFactory.CreateUnix(fileName, mapAsImage); - } - } -} diff --git a/Plugins/dnlib/IO/DataReaderStream.cs b/Plugins/dnlib/IO/DataReaderStream.cs deleted file mode 100644 index 829e3e6..0000000 --- a/Plugins/dnlib/IO/DataReaderStream.cs +++ /dev/null @@ -1,69 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; - -namespace dnlib.IO { - sealed class DataReaderStream : Stream { - public override bool CanRead => true; - public override bool CanSeek => true; - public override bool CanWrite => false; - public override long Length => reader.Length; - - public override long Position { - get => position; - set => position = value; - } - - DataReader reader; - long position; - - public DataReaderStream(in DataReader reader) { - this.reader = reader; - position = reader.Position; - } - - public override void Flush() { } - - bool CheckAndSetPosition() { - if ((ulong)position > reader.Length) - return false; - reader.Position = (uint)position; - return true; - } - - public override long Seek(long offset, SeekOrigin origin) { - switch (origin) { - case SeekOrigin.Begin: Position = offset; break; - case SeekOrigin.Current: Position += offset; break; - case SeekOrigin.End: Position = Length + offset; break; - } - return Position; - } - - public override int Read(byte[] buffer, int offset, int count) { - if (buffer is null) - throw new ArgumentNullException(nameof(buffer)); - if (offset < 0) - throw new ArgumentOutOfRangeException(nameof(offset)); - if (count < 0) - throw new ArgumentOutOfRangeException(nameof(count)); - if (!CheckAndSetPosition()) - return 0; - int bytesToRead = (int)Math.Min((uint)count, reader.BytesLeft); - reader.ReadBytes(buffer, offset, bytesToRead); - Position += bytesToRead; - return bytesToRead; - } - - public override int ReadByte() { - if (!CheckAndSetPosition() || !reader.CanRead(1U)) - return -1; - Position++; - return reader.ReadByte(); - } - - public override void SetLength(long value) => throw new NotSupportedException(); - public override void Write(byte[] buffer, int offset, int count) => throw new NotSupportedException(); - } -} diff --git a/Plugins/dnlib/IO/DataStream.cs b/Plugins/dnlib/IO/DataStream.cs deleted file mode 100644 index 6bdb959..0000000 --- a/Plugins/dnlib/IO/DataStream.cs +++ /dev/null @@ -1,167 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Text; - -namespace dnlib.IO { - /// - /// This class is used by a . The instance - /// verifies that all input are valid before calling any methods in this class. - /// This class is thread safe. - /// - public abstract class DataStream { - /// - /// Reads bytes - /// - /// Offset of data - /// Destination pointer - /// Number of bytes to read - public unsafe abstract void ReadBytes(uint offset, void* destination, int length); - - /// - /// Reads bytes - /// - /// Offset of data - /// Destination array - /// Destination index - /// Number of bytes to read - public abstract void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length); - - /// - /// Reads a - /// - /// Offset of data - /// - public abstract byte ReadByte(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - 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 - /// - /// Offset of data - /// - public abstract ushort ReadUInt16(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - 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 - /// - /// Offset of data - /// - public abstract uint ReadUInt32(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public virtual int ReadInt32(uint offset) => (int)ReadUInt32(offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public abstract ulong ReadUInt64(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public virtual long ReadInt64(uint offset) => (long)ReadUInt64(offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public abstract float ReadSingle(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public abstract double ReadDouble(uint offset); - - /// - /// Reads a - /// - /// Offset of data - /// - public virtual Guid ReadGuid(uint offset) => - new Guid(ReadUInt32(offset), ReadUInt16(offset + 4), ReadUInt16(offset + 6), - 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 - /// - /// Offset of data - /// Number of characters to read - /// - public abstract string ReadUtf16String(uint offset, int chars); - - /// - /// Reads a string - /// - /// Offset of data - /// Length of string in bytes - /// Encoding - /// - public abstract string ReadString(uint offset, int length, Encoding encoding); - - /// - /// Gets the data offset of a byte or returns false if the byte wasn't found - /// - /// Offset of data - /// End offset of data (not inclusive) - /// Byte value to search for - /// Offset of the byte if found - /// - public abstract bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset); - } -} diff --git a/Plugins/dnlib/IO/DataStreamFactory.cs b/Plugins/dnlib/IO/DataStreamFactory.cs deleted file mode 100644 index 808d6e9..0000000 --- a/Plugins/dnlib/IO/DataStreamFactory.cs +++ /dev/null @@ -1,56 +0,0 @@ -// 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(); - - 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 - /// - /// Pointer to data - /// - public static DataStream Create(byte* data) { - if (data is null) - throw new ArgumentNullException(nameof(data)); - if (supportsUnalignedAccesses) - return new UnalignedNativeMemoryDataStream(data); - return new AlignedNativeMemoryDataStream(data); - } - - /// - /// Creates a that reads from a byte array - /// - /// Data - /// - public static DataStream Create(byte[] data) { - if (data is null) - throw new ArgumentNullException(nameof(data)); - if (supportsUnalignedAccesses) - return new UnalignedByteArrayDataStream(data); - return new AlignedByteArrayDataStream(data); - } - } -} diff --git a/Plugins/dnlib/IO/EmptyDataStream.cs b/Plugins/dnlib/IO/EmptyDataStream.cs deleted file mode 100644 index 5c83c51..0000000 --- a/Plugins/dnlib/IO/EmptyDataStream.cs +++ /dev/null @@ -1,33 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Text; - -namespace dnlib.IO { - sealed unsafe class EmptyDataStream : DataStream { - public static readonly DataStream Instance = new EmptyDataStream(); - - EmptyDataStream() { } - - public override void ReadBytes(uint offset, void* destination, int length) { - var p = (byte*)destination; - for (int i = 0; i < length; i++) - *p = 0; - } - public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) { - for (int i = 0; i < length; i++) - destination[destinationIndex + i] = 0; - } - public override byte ReadByte(uint offset) => 0; - public override ushort ReadUInt16(uint offset) => 0; - public override uint ReadUInt32(uint offset) => 0; - public override ulong ReadUInt64(uint offset) => 0; - public override float ReadSingle(uint offset) => 0; - public override double ReadDouble(uint offset) => 0; - public override string ReadUtf16String(uint offset, int chars) => string.Empty; - public override string ReadString(uint offset, int length, Encoding encoding) => string.Empty; - public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) { - valueOffset = 0; - return false; - } - } -} diff --git a/Plugins/dnlib/IO/FileOffset.cs b/Plugins/dnlib/IO/FileOffset.cs deleted file mode 100644 index 882fe3c..0000000 --- a/Plugins/dnlib/IO/FileOffset.cs +++ /dev/null @@ -1,25 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.IO { - /// - /// Represents a file offset - /// - public enum FileOffset : uint { - } - - partial class IOExtensions { - /// - /// Align up - /// - /// this - /// Alignment - 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) => (FileOffset)(((uint)offset + alignment - 1) & ~(alignment - 1)); - } -} diff --git a/Plugins/dnlib/IO/FileSection.cs b/Plugins/dnlib/IO/FileSection.cs deleted file mode 100644 index f0413a5..0000000 --- a/Plugins/dnlib/IO/FileSection.cs +++ /dev/null @@ -1,41 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Diagnostics; - -namespace dnlib.IO { - /// - /// Base class for classes needing to implement IFileSection - /// - [DebuggerDisplay("O:{startOffset} L:{size} {GetType().Name}")] - public class FileSection : IFileSection { - /// - /// The start file offset of this section - /// - protected FileOffset startOffset; - - /// - /// Size of the section - /// - protected uint size; - - /// - public FileOffset StartOffset => startOffset; - - /// - public FileOffset EndOffset => startOffset + size; - - /// - /// Set to 's current position - /// - /// The reader - protected void SetStartOffset(ref DataReader reader) => - startOffset = (FileOffset)reader.CurrentOffset; - - /// - /// Set according to 's current position - /// - /// The reader - protected void SetEndoffset(ref DataReader reader) => - size = reader.CurrentOffset - (uint)startOffset; - } -} diff --git a/Plugins/dnlib/IO/IFileSection.cs b/Plugins/dnlib/IO/IFileSection.cs deleted file mode 100644 index 7be48cd..0000000 --- a/Plugins/dnlib/IO/IFileSection.cs +++ /dev/null @@ -1,19 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.IO { - /// - /// Represents a section in a file - /// - public interface IFileSection { - /// - /// Start offset of the section in the file - /// - FileOffset StartOffset { get; } - - /// - /// End offset of the section in the file. This is one byte after the last - /// valid offset in the section. - /// - FileOffset EndOffset { get; } - } -} diff --git a/Plugins/dnlib/IO/IOExtensions.cs b/Plugins/dnlib/IO/IOExtensions.cs deleted file mode 100644 index 719cdd2..0000000 --- a/Plugins/dnlib/IO/IOExtensions.cs +++ /dev/null @@ -1,9 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.IO { - /// - /// Extension methods - /// - public static partial class IOExtensions { - } -} diff --git a/Plugins/dnlib/IO/MemoryMappedDataReaderFactory.cs b/Plugins/dnlib/IO/MemoryMappedDataReaderFactory.cs deleted file mode 100644 index dc1a64f..0000000 --- a/Plugins/dnlib/IO/MemoryMappedDataReaderFactory.cs +++ /dev/null @@ -1,325 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Threading; -using Microsoft.Win32.SafeHandles; - -namespace dnlib.IO { - /// - /// Creates s that read memory mapped data - /// - sealed unsafe class MemoryMappedDataReaderFactory : DataReaderFactory { - /// - /// The filename or null if the data is not from a file - /// - public override string Filename => filename; - - /// - /// Gets the total length of the data - /// - public override uint Length => length; - - /// - /// Raised when all cached s created by this instance must be recreated - /// - public override event EventHandler DataReaderInvalidated; - - DataStream stream; - uint length; - string filename; - GCHandle gcHandle; - byte[] dataAry; - IntPtr data; - OSType osType; - long origDataLength; - - MemoryMappedDataReaderFactory(string filename) { - osType = OSType.Unknown; - this.filename = filename; - } - - ~MemoryMappedDataReaderFactory() { - Dispose(false); - } - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public override DataReader CreateReader(uint offset, uint length) => CreateReader(stream, offset, length); - - /// - /// Cleans up and frees all allocated memory - /// - public override void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - internal void SetLength(uint length) => this.length = length; - - enum OSType : byte { - Unknown, - Windows, - Unix, - } - - [Serializable] - sealed class MemoryMappedIONotSupportedException : IOException { - public MemoryMappedIONotSupportedException(string s) : base(s) { } - public MemoryMappedIONotSupportedException(SerializationInfo info, StreamingContext context) : base(info, context) { } - } - - static class Windows { - const uint GENERIC_READ = 0x80000000; - const uint FILE_SHARE_READ = 0x00000001; - const uint OPEN_EXISTING = 3; - const uint FILE_ATTRIBUTE_NORMAL = 0x00000080; - const uint PAGE_READONLY = 0x02; - const uint SEC_IMAGE = 0x1000000; - const uint SECTION_MAP_READ = 0x0004; - const uint FILE_MAP_READ = SECTION_MAP_READ; - - [DllImport("kernel32", SetLastError = true, CharSet = CharSet.Auto)] - static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess, uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, uint dwFlagsAndAttributes, IntPtr hTemplateFile); - - [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] - static extern SafeFileHandle CreateFileMapping(SafeFileHandle hFile, IntPtr lpAttributes, uint flProtect, uint dwMaximumSizeHigh, uint dwMaximumSizeLow, string lpName); - - [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] - static extern IntPtr MapViewOfFile(SafeFileHandle hFileMappingObject, uint dwDesiredAccess, uint dwFileOffsetHigh, uint dwFileOffsetLow, UIntPtr dwNumberOfBytesToMap); - - [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] - [return: MarshalAs(UnmanagedType.Bool)] - static extern bool UnmapViewOfFile(IntPtr lpBaseAddress); - - [DllImport("kernel32", CharSet = CharSet.Auto, SetLastError = true)] - static extern uint GetFileSize(SafeFileHandle hFile, out uint lpFileSizeHigh); - const uint INVALID_FILE_SIZE = 0xFFFFFFFF; - const int NO_ERROR = 0; - - public static void Mmap(MemoryMappedDataReaderFactory creator, bool mapAsImage) { - using (var fileHandle = CreateFile(creator.filename, GENERIC_READ, FILE_SHARE_READ, IntPtr.Zero, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, IntPtr.Zero)) { - if (fileHandle.IsInvalid) - throw new IOException($"Could not open file {creator.filename} for reading. Error: {Marshal.GetLastWin32Error():X8}"); - - uint sizeLo = GetFileSize(fileHandle, out uint sizeHi); - int hr; - if (sizeLo == INVALID_FILE_SIZE && (hr = Marshal.GetLastWin32Error()) != NO_ERROR) - throw new IOException($"Could not get file size. File: {creator.filename}, 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($"Could not create a file mapping object. File: {creator.filename}, error: {Marshal.GetLastWin32Error():X8}"); - creator.data = MapViewOfFile(fileMapping, FILE_MAP_READ, 0, 0, UIntPtr.Zero); - if (creator.data == IntPtr.Zero) - throw new MemoryMappedIONotSupportedException($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error():X8}"); - creator.length = (uint)fileSize; - creator.osType = OSType.Windows; - creator.stream = DataStreamFactory.Create((byte*)creator.data); - } - } - } - - public static void Dispose(IntPtr addr) { - if (addr != IntPtr.Zero) - UnmapViewOfFile(addr); - } - } - - static class Unix { - // Can't use SafeFileHandle. Seems like a bug in mono. You'll get - // "_wapi_handle_unref_full: Attempting to unref unused handle 0xYYY" when Dispose() is called. - [DllImport("libc")] - static extern int open(string pathname, int flags); - const int O_RDONLY = 0; - - [DllImport("libc")] - static extern int close(int fd); - - [DllImport("libc", EntryPoint = "lseek", SetLastError = true)] - static extern int lseek32(int fd, int offset, int whence); - [DllImport("libc", EntryPoint = "lseek", SetLastError = true)] - static extern long lseek64(int fd, long offset, int whence); - const int SEEK_END = 2; - - [DllImport("libc", EntryPoint = "mmap", SetLastError = true)] - static extern IntPtr mmap32(IntPtr addr, IntPtr length, int prot, int flags, int fd, int offset); - [DllImport("libc", EntryPoint = "mmap", SetLastError = true)] - static extern IntPtr mmap64(IntPtr addr, IntPtr length, int prot, int flags, int fd, long offset); - const int PROT_READ = 1; - const int MAP_PRIVATE = 0x02; - - [DllImport("libc")] - static extern int munmap(IntPtr addr, IntPtr length); - - public static void Mmap(MemoryMappedDataReaderFactory creator, bool mapAsImage) { - int fd = open(creator.filename, O_RDONLY); - try { - if (fd < 0) - throw new IOException($"Could not open file {creator.filename} for reading. Error: {fd}"); - - long size; - IntPtr data; - - if (IntPtr.Size == 4) { - size = lseek32(fd, 0, SEEK_END); - if (size == -1) - throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.filename} (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($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error()}"); - } - else { - size = lseek64(fd, 0, SEEK_END); - if (size == -1) - throw new MemoryMappedIONotSupportedException($"Could not get length of {creator.filename} (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($"Could not map file {creator.filename}. Error: {Marshal.GetLastWin32Error()}"); - } - - creator.data = data; - creator.length = (uint)size; - creator.origDataLength = size; - creator.osType = OSType.Unix; - creator.stream = DataStreamFactory.Create((byte*)creator.data); - } - finally { - if (fd >= 0) - close(fd); - } - } - - public static void Dispose(IntPtr addr, long size) { - if (addr != IntPtr.Zero) - munmap(addr, new IntPtr(size)); - } - } - - static volatile bool canTryWindows = true; - static volatile bool canTryUnix = true; - - internal static MemoryMappedDataReaderFactory CreateWindows(string filename, bool mapAsImage) { - if (!canTryWindows) - return null; - - var creator = new MemoryMappedDataReaderFactory(GetFullPath(filename)); - try { - Windows.Mmap(creator, mapAsImage); - return creator; - } - catch (EntryPointNotFoundException) { - } - catch (DllNotFoundException) { - } - canTryWindows = false; - return null; - } - - internal static MemoryMappedDataReaderFactory CreateUnix(string filename, bool mapAsImage) { - if (!canTryUnix) - return null; - - var creator = new MemoryMappedDataReaderFactory(GetFullPath(filename)); - try { - Unix.Mmap(creator, mapAsImage); - if (mapAsImage) { // Only check this if we know that mmap() works, i.e., if above call succeeds - creator.Dispose(); - throw new ArgumentException("mapAsImage == true is not supported on this OS"); - } - return creator; - } - catch (MemoryMappedIONotSupportedException ex) { - Debug.WriteLine($"mmap'd IO didn't work: {ex.Message}"); - } - catch (EntryPointNotFoundException) { - } - catch (DllNotFoundException) { - } - canTryUnix = false; - return null; - } - - static string GetFullPath(string filename) { - try { - return Path.GetFullPath(filename); - } - catch { - return filename; - } - } - - void Dispose(bool disposing) { - FreeMemoryMappedIoData(); - if (disposing) { - length = 0; - stream = EmptyDataStream.Instance; - data = IntPtr.Zero; - filename = null; - } - } - - /// - /// true if memory mapped I/O is enabled - /// - 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 is not null) - return; - var newAry = new byte[length]; - Marshal.Copy(data, newAry, 0, newAry.Length); - FreeMemoryMappedIoData(); - length = (uint)newAry.Length; - dataAry = newAry; - gcHandle = GCHandle.Alloc(dataAry, GCHandleType.Pinned); - data = gcHandle.AddrOfPinnedObject(); - stream = DataStreamFactory.Create((byte*)data); - DataReaderInvalidated?.Invoke(this, EventArgs.Empty); - } - - void FreeMemoryMappedIoData() { - if (dataAry is null) { - var origData = Interlocked.Exchange(ref data, IntPtr.Zero); - if (origData != IntPtr.Zero) { - length = 0; - switch (osType) { - case OSType.Windows: - Windows.Dispose(origData); - break; - - case OSType.Unix: - Unix.Dispose(origData, origDataLength); - break; - - default: - throw new InvalidOperationException("Shouldn't be here"); - } - } - } - - if (gcHandle.IsAllocated) { - try { - gcHandle.Free(); - } - catch (InvalidOperationException) { - } - } - dataAry = null; - } - } -} diff --git a/Plugins/dnlib/IO/NativeMemoryDataReaderFactory.cs b/Plugins/dnlib/IO/NativeMemoryDataReaderFactory.cs deleted file mode 100644 index c2746e0..0000000 --- a/Plugins/dnlib/IO/NativeMemoryDataReaderFactory.cs +++ /dev/null @@ -1,62 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.IO { - /// - /// Creates s that read native memory - /// - public sealed unsafe class NativeMemoryDataReaderFactory : DataReaderFactory { - /// - /// The filename or null if the data is not from a file - /// - public override string Filename => filename; - - /// - /// Gets the total length of the data - /// - public override uint Length => length; - - DataStream stream; - string filename; - uint length; - - NativeMemoryDataReaderFactory(byte* data, uint length, string filename) { - this.filename = filename; - this.length = length; - stream = DataStreamFactory.Create(data); - } - - internal void SetLength(uint length) => this.length = length; - - /// - /// Creates a instance - /// - /// Pointer to data - /// Length of data - /// The filename or null if the data is not from a file - /// - public static NativeMemoryDataReaderFactory Create(byte* data, uint length, string filename) { - if (data is null) - throw new ArgumentNullException(nameof(data)); - return new NativeMemoryDataReaderFactory(data, length, filename); - } - - /// - /// Creates a data reader - /// - /// Offset of data - /// Length of data - /// - public override DataReader CreateReader(uint offset, uint length) => CreateReader(stream, offset, length); - - /// - /// This method doesn't need to be called since this instance doesn't own the native memory - /// - public override void Dispose() { - stream = EmptyDataStream.Instance; - length = 0; - filename = null; - } - } -} diff --git a/Plugins/dnlib/IO/UnalignedByteArrayDataStream.cs b/Plugins/dnlib/IO/UnalignedByteArrayDataStream.cs deleted file mode 100644 index 9b7d497..0000000 --- a/Plugins/dnlib/IO/UnalignedByteArrayDataStream.cs +++ /dev/null @@ -1,105 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace dnlib.IO { - sealed unsafe class UnalignedByteArrayDataStream : DataStream { - readonly byte[] data; - - public UnalignedByteArrayDataStream(byte[] data) => this.data = data; - - public override void ReadBytes(uint offset, void* destination, int length) => - Marshal.Copy(data, (int)offset, (IntPtr)destination, length); - - public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => - Array.Copy(data, (int)offset, destination, destinationIndex, length); - - public override byte ReadByte(uint offset) => data[(int)offset]; - - public override ushort ReadUInt16(uint offset) { - int i = (int)offset; - var data = this.data; - return (ushort)(data[i++] | (data[i] << 8)); - } - - public override uint ReadUInt32(uint offset) { - fixed (byte* p = data) - return *(uint*)(p + offset); - } - - public override ulong ReadUInt64(uint offset) { - fixed (byte* p = data) - return *(ulong*)(p + offset); - } - - public override float ReadSingle(uint offset) { - fixed (byte* p = data) - return *(float*)(p + offset); - } - - public override double ReadDouble(uint offset) { - fixed (byte* p = data) - return *(double*)(p + offset); - } - - public override Guid ReadGuid(uint offset) { - fixed (byte* p = data) - return *(Guid*)(p + offset); - } - - public override string ReadUtf16String(uint offset, int chars) { - fixed (byte* p = data) - return new string((char*)(p + offset), 0, chars); - } - - public override string ReadString(uint offset, int length, Encoding encoding) { - fixed (byte* p = data) - return new string((sbyte*)(p + offset), 0, length, encoding); - } - - public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) { - fixed (byte* pd = data) { - // If this code gets updated, also update the other DataStream implementations - - byte* p = pd + offset; - - uint count = (endOffset - offset) / 4; - for (uint i = 0; i < count; i++) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - - byte* pe = pd + endOffset; - while (p != pe) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - valueOffset = 0; - return false; - } - } - } -} diff --git a/Plugins/dnlib/IO/UnalignedNativeMemoryDataStream.cs b/Plugins/dnlib/IO/UnalignedNativeMemoryDataStream.cs deleted file mode 100644 index 3cbffd8..0000000 --- a/Plugins/dnlib/IO/UnalignedNativeMemoryDataStream.cs +++ /dev/null @@ -1,84 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.InteropServices; -using System.Text; - -namespace dnlib.IO { - sealed unsafe class UnalignedNativeMemoryDataStream : DataStream { - readonly byte* data; - - public UnalignedNativeMemoryDataStream(byte* data) => this.data = data; - - public override void ReadBytes(uint offset, void* destination, int length) { - var ps = data + offset; - var pd = (byte*)destination; - int count = length / 4; - length = length % 4; - for (int i = 0; i < count; i++) { - //TODO: Align one of the pointers. destination is more likely to be aligned - *(uint*)pd = *(uint*)ps; - pd += 4; - ps += 4; - } - for (int i = 0; i < length; i++, ps++, pd++) - *pd = *ps; - } - - public override void ReadBytes(uint offset, byte[] destination, int destinationIndex, int length) => - Marshal.Copy((IntPtr)(data + offset), destination, destinationIndex, length); - - public override byte ReadByte(uint offset) => *(data + offset); - public override ushort ReadUInt16(uint offset) => *(ushort*)(data + offset); - public override uint ReadUInt32(uint offset) => *(uint*)(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); - public override Guid ReadGuid(uint offset) => *(Guid*)(data + offset); - public override string ReadUtf16String(uint offset, int chars) => new string((char*)(data + offset), 0, chars); - public override string ReadString(uint offset, int length, Encoding encoding) => new string((sbyte*)(data + offset), 0, length, encoding); - - public override bool TryGetOffsetOf(uint offset, uint endOffset, byte value, out uint valueOffset) { - var pd = data; - - // If this code gets updated, also update the other DataStream implementations - - byte* p = pd + offset; - - uint count = (endOffset - offset) / 4; - for (uint i = 0; i < count; i++) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - - byte* pe = pd + endOffset; - while (p != pe) { - if (*p == value) { - valueOffset = (uint)(p - pd); - return true; - } - p++; - } - valueOffset = 0; - return false; - } - } -} diff --git a/Plugins/dnlib/IR/ArgumentFamily.cs b/Plugins/dnlib/IR/ArgumentFamily.cs deleted file mode 100644 index a2d5ba0..0000000 --- a/Plugins/dnlib/IR/ArgumentFamily.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace dnlib.IR { - public enum ArgumentFamily { - VariableId, - Constant, - BranchOffset, - Switch, - MultiVariable, - } -} diff --git a/Plugins/dnlib/IR/ArgumentFlag.cs b/Plugins/dnlib/IR/ArgumentFlag.cs deleted file mode 100644 index d2a0b58..0000000 --- a/Plugins/dnlib/IR/ArgumentFlag.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - - -namespace dnlib.IR { - //public class VariableArgumentData : InstructionArgumentData { - // public VariableLocation location; - // public int index; - //} - - [Flags] - public enum ArgumentFlag { - None = 0x0, - Volatible = 0x1, - } -} diff --git a/Plugins/dnlib/IR/ArgumentMetaFlag.cs b/Plugins/dnlib/IR/ArgumentMetaFlag.cs deleted file mode 100644 index be8e8c1..0000000 --- a/Plugins/dnlib/IR/ArgumentMetaFlag.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - - -namespace dnlib.IR { - - [Flags] - public enum ArgumentMetaFlag { - None = 0x0, - In = 0x1, - Out = 0x2, - InOut = In | Out, - LoadAddress = 0x4, - Variadic = 0x8, - Constant = 0x10, - LoadIndirect = 0x20, - StoreIndirect = 0x40, - } -} diff --git a/Plugins/dnlib/IR/BasicBlock.cs b/Plugins/dnlib/IR/BasicBlock.cs deleted file mode 100644 index 16ba100..0000000 --- a/Plugins/dnlib/IR/BasicBlock.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using dnlib.DotNet.Emit; - -namespace dnlib.IR { - public class BasicBlock { - private List _insts = new List(); - - private List _goinVars = new List(); - private List _gooutVars = new List(); - - - public IList Instructions => _insts; - - public void AddInstruction(Instruction inst) { - _insts.Add(inst); - } - } -} diff --git a/Plugins/dnlib/IR/CFG.cs b/Plugins/dnlib/IR/CFG.cs deleted file mode 100644 index 9807fee..0000000 --- a/Plugins/dnlib/IR/CFG.cs +++ /dev/null @@ -1,84 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace dnlib.IR { - class CFG { - - private readonly List _bbs; - private readonly List _exHandlers; - - public CFG(List bbs, List exHandlers) { - _bbs = bbs; - _exHandlers = exHandlers; - } - - - - - - private void BasicBlockForwardDFS(IRBasicBlock bb, Dictionary bb2scc, HashSet visited, Stack stack) { - if (!bb2scc.TryGetValue(bb, out var scc)) { - scc = new StronglyConnectedComponents(); - scc.AddBlock(bb); - bb2scc.Add(bb, scc); - } - - // existing cycle - if (!visited.Add(bb)) { - foreach (var prevBb in stack) { - if (prevBb == bb) { - break; - } - scc.Merge(bb2scc[prevBb], bb2scc); - } - return; - } - - stack.Push(bb); - foreach (var next in bb.OutboundBasicBlocks) { - BasicBlockForwardDFS(next, bb2scc, visited, stack); - } - stack.Pop(); - } - - private void ComputeSccFowardFlows(Dictionary bb2scc) { - var csss = new HashSet(); - foreach (var sc in bb2scc.Values) { - if (csss.Add(sc)) { - sc.InitOutboundSccs(bb2scc); - } - } - } - - private readonly Dictionary _bb2scc = new Dictionary(); - - public StronglyConnectedComponents GetScc(IRBasicBlock bb) { - return _bb2scc[bb]; - } - - public void ComputeControlFlows() { - var visited = new HashSet(); - var stack = new Stack(); - BasicBlockForwardDFS(_bbs[0], _bb2scc, visited, stack); - - foreach (var ex in _exHandlers) { - //if (ex.TryStart != null) { - // BasicBlockForwardDFS(ex.TryStart, bb2scc, visited, stack); - //} - if (ex.HandlerStart != null) { - BasicBlockForwardDFS(ex.HandlerStart, _bb2scc, visited, stack); - } - if (ex.FilterStart != null) { - BasicBlockForwardDFS(ex.FilterStart, _bb2scc, visited, stack); - } - } - - ComputeSccFowardFlows(_bb2scc); - } - - - - // 要计算多个基本块(BasicBlocks)的共同最近的前驱基本块(即最近公共祖先,LCA,Lowest Common Ancestor),你可以使用以下方法。这里假设你有一个控制流图(CFG),其中每个基本块是一个节点,边代表控制流。 - - } -} diff --git a/Plugins/dnlib/IR/ConstType.cs b/Plugins/dnlib/IR/ConstType.cs deleted file mode 100644 index 34b4cea..0000000 --- a/Plugins/dnlib/IR/ConstType.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace dnlib.IR { - public enum ConstType { - Int32, - Int64, - Float, - Double, - String, - Null, - RuntimeHandle, - } -} diff --git a/Plugins/dnlib/IR/EvalStack.cs b/Plugins/dnlib/IR/EvalStack.cs deleted file mode 100644 index 7981b0e..0000000 --- a/Plugins/dnlib/IR/EvalStack.cs +++ /dev/null @@ -1,63 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; - - -namespace dnlib.IR { - public class EvalStack { - private readonly List _stack = new List(); - - - public int Count => _stack.Count; - - public VariableInfo GetTop() { - return _stack[_stack.Count - 1]; - } - - public VariableInfo GetTop(int index) { - return _stack[_stack.Count - 1 - index]; - } - - public void Push(VariableInfo var) { - _stack.Add(var); - } - - public VariableInfo Pop() { - var v = _stack[_stack.Count - 1]; - _stack.RemoveAt(_stack.Count - 1); - return v; - } - - public void Pop(int n) { - _stack.RemoveRange(_stack.Count - n, n); - } - - public VariableInfo[] PopWithValue(int n) { - var vars = _stack.GetRange(_stack.Count - n, n).ToArray(); - _stack.RemoveRange(_stack.Count - n, n); - return vars; - } - - public void Clear() { - _stack.Clear(); - } - - public void LoadInbound(IRBasicBlock bb) { - _stack.Clear(); - _stack.AddRange(bb.InboundVariables); - } - - public void SaveInbound(IRBasicBlock bb) { - if (bb.InboundVariables.Count == 0) { - if (_stack.Count > 0) { - bb.SetInboundVariables(_stack); - } - } else { - Debug.Assert(bb.InboundVariables.Count == _stack.Count); - } - } - - public void SaveOutbound(IRBasicBlock bb) { - bb.SetOutboundVariables(_stack); - } - } -} diff --git a/Plugins/dnlib/IR/IRBasicBlock.cs b/Plugins/dnlib/IR/IRBasicBlock.cs deleted file mode 100644 index 6bedee6..0000000 --- a/Plugins/dnlib/IR/IRBasicBlock.cs +++ /dev/null @@ -1,104 +0,0 @@ -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; - - -namespace dnlib.IR { - public class IRBasicBlock { - public IRBasicBlock nextIrbb; - - public BasicBlock ilbb; - - private readonly List _insts = new List(); - - private readonly List _inboundVars = new List(); - - private readonly List _outboundVars = new List(); - - private readonly List _inboundBbs = new List(); - - private readonly List _outboundBbs = new List(); - - public List Instructions => _insts; - - public IList InboundVariables => _inboundVars; - - public IList OutboundVariables => _outboundVars; - - public IList InboundBasicBlocks => _inboundBbs; - - public IList OutboundBasicBlocks => _outboundBbs; - - public int IROffset { get; set; } = -1; - - public void AddInstruction(IRInstruction inst) { - VerifyInstruction(inst); - _insts.Add(inst); - } - - private void VerifyInstruction(IRInstruction inst) { - var meta = InstructionMeta.Get(inst.opcode); - - if (meta.args.Count != inst.args.Count) { - Debug.Fail($"Instruction {inst.opcode} has {inst.args.Count} arguments, but {meta.args.Count} are expected."); - } - - for (int i = 0; i < inst.args.Count; i++) { - var arg = inst.args[i]; - var argMeta = meta.args[i]; - if ((argMeta.flag & ArgumentMetaFlag.Constant) != 0) { - if (!(arg is InstructionArgumentConstant)) { - Debug.Fail($"Argument {i} of instruction {inst.opcode} should be constant."); - } - } - else if ((argMeta.flag & ArgumentMetaFlag.Variadic) != 0) { - if (!(arg is InstructionArgumentMultiVariable)) { - Debug.Fail($"Argument {i} of instruction {inst.opcode} should be variable."); - } - } else { - if (arg != null && !(arg is InstructionArgumentVariable)) { - Debug.Fail($"Argument {i} of instruction {inst.opcode} should be variable."); - } - } - } - - if ((meta.flag & (InstructionFlag.InlineToken | InstructionFlag.InlineOffset)) != 0) { - Debug.Assert(inst.inlineOperand != null, "inline operand should be null"); - } - } - - //public void PushEvalStack(VariableInfo v) { - // _inboundVars.Add(v); - //} - - //public void PushEvalStack(IList vs) { - // _inboundVars.AddRange(vs); - //} - - public void SetInboundVariable(VariableInfo variable) { - SetInboundVariables(new VariableInfo[] { variable }); - } - - public void SetInboundVariables(IList vs) { - - if (_inboundVars.Count == 0) { - _inboundVars.AddRange(vs); - } - else { - Debug.Assert(_inboundVars.Count == vs.Count); - } - } - - public void SetOutboundVariables(IList vs) { - _outboundVars.Clear(); - _outboundVars.AddRange(vs); - } - - public void AddOutboundBasicBlock(IRBasicBlock target) { - if (target != this && !_outboundBbs.Contains(target)) { - _outboundBbs.Add(target); - target._inboundBbs.Add(this); - } - } - } -} diff --git a/Plugins/dnlib/IR/IRExceptionHandler.cs b/Plugins/dnlib/IR/IRExceptionHandler.cs deleted file mode 100644 index f5302f0..0000000 --- a/Plugins/dnlib/IR/IRExceptionHandler.cs +++ /dev/null @@ -1,22 +0,0 @@ -using dnlib.DotNet; -using dnlib.DotNet.Emit; - - -namespace dnlib.IR { - public class IRExceptionHandler { - - public IRBasicBlock TryStart; - - public IRBasicBlock TryEnd; - - public IRBasicBlock FilterStart; - - public IRBasicBlock HandlerStart; - - public IRBasicBlock HandlerEnd; - - public ITypeDefOrRef CatchType; - - public ExceptionHandlerType HandlerType; - } -} diff --git a/Plugins/dnlib/IR/IRFamily.cs b/Plugins/dnlib/IR/IRFamily.cs deleted file mode 100644 index 2cfe512..0000000 --- a/Plugins/dnlib/IR/IRFamily.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace dnlib.IR { - public enum IRFamily { - Unspec, - PushOrPopVariable, - LoadOrSet, - LoadAddress, - LoadIndirect, - StoreIndirect, - LoadConstant, - Call, - Ret, - Branch, - BinOp, - UnOp, - Conv, - Obj, - Cast, - Box, - Exception, - Field, - Array, - Compare, - Ldftn, - Ref, - } -} diff --git a/Plugins/dnlib/IR/IRInstruction.cs b/Plugins/dnlib/IR/IRInstruction.cs deleted file mode 100644 index a4b2b50..0000000 --- a/Plugins/dnlib/IR/IRInstruction.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; - - -namespace dnlib.IR { - - public enum PrefixCode { - None, - Constrained, - No, - ReadOnly, - Tail, - Unaligned, - Volatile, - } - - public struct PrefixData { - public PrefixCode code; - public object data; - } - - - public class IRInstruction { - public IRFamily family; - public IROpCode opcode; - public List args; - public PrefixData? prefixData; - public object inlineOperand; - public int index; - - public static IRInstruction Create(IRFamily family, IROpCode opcode, params InstructionArgument[] args) { - return new IRInstruction { - family = family, - opcode = opcode, - args = new List(args), - }; - } - - public static IRInstruction Create(IRFamily family, IROpCode opcode, IRBasicBlock target, params InstructionArgument[] args) { - return new IRInstruction { - family = family, - opcode = opcode, - args = new List(args), - inlineOperand = target, - }; - } - - public static IRInstruction Create(IRFamily family, IROpCode opcode, IRBasicBlock[] targets, params InstructionArgument[] args) { - return new IRInstruction { - family = family, - opcode = opcode, - args = new List(args), - inlineOperand = targets, - }; - } - - public static IRInstruction Create(IRFamily family, IROpCode opcode, PrefixData? prefixData, params InstructionArgument[] args) { - return new IRInstruction { - family = family, - opcode = opcode, - prefixData = prefixData, - args = new List(args), - }; - } - } -} diff --git a/Plugins/dnlib/IR/IRMethodBody.cs b/Plugins/dnlib/IR/IRMethodBody.cs deleted file mode 100644 index 2f5332f..0000000 --- a/Plugins/dnlib/IR/IRMethodBody.cs +++ /dev/null @@ -1,202 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - - -namespace dnlib.IR { - - public class IRMethodBody { - - public MethodDef MethodDef { get; } - - public List ExceptionHandlers { get; } - - public List BasicBlocks { get; private set; } - - public VariableSet VariableSet { get; private set; } - - private CFG _cfg; - - private class LocalVariable { - public LocalVariable prev; - public VariableInfo variableInfo; - } - - private List _localVariables; - - public IRMethodBody(MethodDef methodDef, List exceptionHandlers, VariableSet variableSet, List basicBlocks) { - MethodDef = methodDef; - ExceptionHandlers = exceptionHandlers; - VariableSet = variableSet; - BasicBlocks = basicBlocks; - } - - public void ApplyOptimizations() { - RemoveUnusedBasicBlocks(); - RemoveAllUnusedVariales(); - RebuildInstructionIds(); - BuildLocalVariables(); - - //_cfg = new CFG(BasicBlocks, ExceptionHandlers); - //_cfg.ComputeControlFlows(); - - //BuildVariableScopes(); - } - - - private void RebuildInstructionIds() { - int nextIndex = 0; - foreach (var bb in BasicBlocks) { - foreach (var inst in bb.Instructions) { - inst.index = nextIndex++; - } - } - } - - private HashSet ComputeUsedVariables() { - var usedVars = new HashSet(); - foreach (var bb in BasicBlocks) { - foreach (var inst in bb.Instructions) { - foreach (var op in inst.args) { - if (op is InstructionArgumentVariable iav) { - usedVars.Add(iav.value); - } - else if (op is InstructionArgumentMultiVariable iamv) { - foreach (var v in iamv.values) { - usedVars.Add(v); - } - } - } - } - } - return usedVars; - } - - - private void RemoveAllUnusedVariales() { - var usedVars = ComputeUsedVariables(); - VariableSet = VariableSet.Rebuild(usedVars); - } - - private void WalkBasicBlock(IRBasicBlock bb, HashSet visited) { - if (!visited.Add(bb)) { - return; - } - foreach (var next in bb.OutboundBasicBlocks) { - WalkBasicBlock(next, visited); - } - } - - private HashSet ComputeUsedBlocks() { - var usedBlocks = new HashSet(); - WalkBasicBlock(BasicBlocks[0], usedBlocks); - foreach (var ex in ExceptionHandlers) { - if (ex.TryStart != null) { - WalkBasicBlock(ex.TryStart, usedBlocks); - } - if (ex.HandlerStart != null) { - WalkBasicBlock(ex.HandlerStart, usedBlocks); - } - if (ex.FilterStart != null) { - WalkBasicBlock(ex.FilterStart, usedBlocks); - } - } - return usedBlocks; - } - - private void RemoveUnusedBasicBlocks() { - var usedBlocks = ComputeUsedBlocks(); - var oldBasicBlocks = BasicBlocks; - var newBasicBlocks = BasicBlocks.Where(usedBlocks.Contains).ToList(); - BasicBlocks = newBasicBlocks; - int oldBasicBlocksCount = oldBasicBlocks.Count; - int newBasicBlocksCount = BasicBlocks.Count; - if (newBasicBlocksCount != oldBasicBlocksCount) { - Console.WriteLine($"original BasicBlock count:{oldBasicBlocksCount}, trimed count:{newBasicBlocksCount}, Removed {oldBasicBlocksCount - newBasicBlocksCount} unused basic blocks"); - } - } - - - private void BuildLocalVariables() { - _localVariables = VariableSet.Variables.Select(v => new LocalVariable { variableInfo = v }).ToList(); - - LocalVariable prevLocal = null; - - foreach (var loc in _localVariables) { - Debug.Assert(_localVariables[loc.variableInfo.id] == loc); - if (loc.variableInfo.location == VariableLocation.Argument) { - continue; - } - if (prevLocal != null) { - loc.prev = prevLocal; - } - prevLocal = loc; - } - } - - private class VariableScope { - - //private readonly Dictionary _lastBbUsedInsts = new Dictionary(); - - private readonly HashSet _belongBbs = new HashSet(); - - public StronglyConnectedComponents PrevCommonAncestor { get; private set; } - - public StronglyConnectedComponents NextCommonAncestor { get; private set; } - - public void AddBlock(StronglyConnectedComponents bb) { - //_lastBbUsedInsts[bb] = inst; - _belongBbs.Add(bb); - } - - public void SetupCommonAncestors(CFG cfg) { - - if (_belongBbs.Count == 1) { - PrevCommonAncestor = NextCommonAncestor = _belongBbs.First(); - return; - } - - - } - } - - private Dictionary CreateVariableScopes() { - var varScopes = new Dictionary(); - foreach (var bb in this.BasicBlocks) { - var scc = _cfg.GetScc(bb); - foreach (var inst in bb.Instructions) { - foreach (var op in inst.args) { - if (op is InstructionArgumentVariable iav) { - if (!varScopes.TryGetValue(iav.value, out var scope)) { - scope = new VariableScope(); - varScopes[iav.value] = scope; - } - scope.AddBlock(scc); - } - else if (op is InstructionArgumentMultiVariable iamv) { - foreach (var v in iamv.values) { - if (!varScopes.TryGetValue(v, out var scope)) { - scope = new VariableScope(); - varScopes[v] = scope; - } - scope.AddBlock(scc); - } - } - } - } - } - return varScopes; - } - - - private void BuildVariableScopes() { - var varScopes = CreateVariableScopes(); - foreach (var scope in varScopes.Values) { - scope.SetupCommonAncestors(_cfg); - } - } - } -} diff --git a/Plugins/dnlib/IR/IROpCode.cs b/Plugins/dnlib/IR/IROpCode.cs deleted file mode 100644 index c02024b..0000000 --- a/Plugins/dnlib/IR/IROpCode.cs +++ /dev/null @@ -1,142 +0,0 @@ -namespace dnlib.IR { - public enum IROpCode { - LoadOrSet, - LoadAddress, - LoadConstant, - Call, - CallI, - CallVir, - NewObj, - Ret, - UnconditionBranch, - BranchFalse, - BranchTrue, - Beq, - Bge, - Bgt, - Ble, - Blt, - Bne_Un, - Bge_Un, - Bgt_Un, - Ble_Un, - Blt_Un, - Switch, - Ceq, - Cgt, - Cgt_Un, - Clt, - Clt_Un, - LoadIndirect, - StoreIndirect, - Add, - Add_Ovf, - Add_Ovf_Un, - Sub, - Sub_Ovf, - Sub_Ovf_Un, - Mul, - Mul_Ovf, - Mul_Ovf_Un, - Div, - Div_Un, - Rem, - Rem_Un, - And, - Or, - Xor, - Shl, - Shr, - Shr_Un, - Neg, - Not, - Conv_I1, - Conv_I2, - Conv_I4, - Conv_I8, - Conv_U1, - Conv_U2, - Conv_U4, - Conv_U8, - Conv_I, - Conv_U, - Conv_R4, - Conv_R8, - Conv_Ovf_I1, - Conv_Ovf_I2, - Conv_Ovf_I4, - Conv_Ovf_I8, - Conv_Ovf_U1, - Conv_Ovf_U2, - Conv_Ovf_U4, - Conv_Ovf_U8, - Conv_Ovf_I, - Conv_Ovf_U, - Conv_Ovf_I1_Un, - Conv_Ovf_I2_Un, - Conv_Ovf_I4_Un, - Conv_Ovf_I8_Un, - Conv_Ovf_U1_Un, - Conv_Ovf_U2_Un, - Conv_Ovf_U4_Un, - Conv_Ovf_U8_Un, - Conv_Ovf_I_Un, - Conv_Ovf_U_Un, - InitObj, - CpObj, - LdObj, - StObj, - CastClass, - IsInst, - Box, - Unbox, - Unbox_Any, - Throw, - Rethrow, - Leave, - EndFinallyOrFault, - EndFilter, - LoadExceptionObject, - Ldfld, - Ldflda, - Stfld, - Ldsfld, - Ldsflda, - Stsfld, - Newarr, - LdLen, - Ldelema, - Ldelem_I1, - Ldelem_U1, - Ldelem_I2, - Ldelem_U2, - Ldelem_I4, - Ldelem_U4, - Ldelem_I8, - Ldelem_I, - Ldelem_R4, - Ldelem_R8, - Ldelem_Ref, - Stelem_I, - Stelem_I1, - Stelem_I2, - Stelem_I4, - Stelem_I8, - Stelem_R4, - Stelem_R8, - Stelem_Ref, - Ldelem, - Stelem, - Ldftn, - Ldvirtftn, - Localloc, - Cpblk, - Initblk, - Sizeof, - Mkrefany, - Refanytype, - Refanyval, - Ckfinite, - Ldtoken, - } -} diff --git a/Plugins/dnlib/IR/IRTransformer.cs b/Plugins/dnlib/IR/IRTransformer.cs deleted file mode 100644 index bd0d215..0000000 --- a/Plugins/dnlib/IR/IRTransformer.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Linq; -using System.Reflection; -using System.Text; -using System.Xml.Linq; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - - -namespace dnlib.IR { - - public class IRTransformer { - public IRMethodBody Transform(MethodDef method) { - - Console.WriteLine($"Method: {method.FullName}"); - if (!method.HasBody) { - return null; - } - var ctx = new TransformContext(method); - return ctx.Transform(); - } - } -} diff --git a/Plugins/dnlib/IR/InstructionArgument.cs b/Plugins/dnlib/IR/InstructionArgument.cs deleted file mode 100644 index f839b40..0000000 --- a/Plugins/dnlib/IR/InstructionArgument.cs +++ /dev/null @@ -1,67 +0,0 @@ -namespace dnlib.IR { - public class InstructionArgument { - public ArgumentFamily family; - public ArgumentFlag flag; - //public object value; - - - public static InstructionArgument CreateVariable(VariableInfo varInfo, ArgumentFlag flag = ArgumentFlag.None) { - return new InstructionArgumentVariable { - family = ArgumentFamily.VariableId, - flag = flag, - value = varInfo, - }; - } - - public static InstructionArgument CreateMultiVariable(params VariableInfo[] varInfos) { - return new InstructionArgumentMultiVariable { - family = ArgumentFamily.MultiVariable, - flag = ArgumentFlag.None, - values = varInfos, - }; - } - - public static InstructionArgumentConstant CreateConst(TypedConst value) { - return new InstructionArgumentConstant { - family = ArgumentFamily.Constant, - flag = ArgumentFlag.None, - value = value, - }; - } - - //public static InstructionArgumentTarget CreateBranchTarget(IRBasicBlock target) { - // return new InstructionArgumentTarget { - // family = ArgumentFamily.BranchOffset, - // flag = ArgumentFlag.None, - // target = target, - // }; - //} - - //public static InstructionArgumentSwitch CreateSwitch(IRBasicBlock[] cases) { - // return new InstructionArgumentSwitch { - // family = ArgumentFamily.Switch, - // flag = ArgumentFlag.None, - // cases = cases, - // }; - //} - } - - public class InstructionArgumentVariable : InstructionArgument { - public VariableInfo value; - } - public class InstructionArgumentMultiVariable : InstructionArgument { - public VariableInfo[] values; - } - - public class InstructionArgumentConstant : InstructionArgument { - public TypedConst value; - } - - //public class InstructionArgumentTarget : InstructionArgument { - // public IRBasicBlock target; - //} - - //public class InstructionArgumentSwitch : InstructionArgument { - // public IRBasicBlock[] cases; - //} -} diff --git a/Plugins/dnlib/IR/InstructionArgumentMeta.cs b/Plugins/dnlib/IR/InstructionArgumentMeta.cs deleted file mode 100644 index 1d3cff3..0000000 --- a/Plugins/dnlib/IR/InstructionArgumentMeta.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace dnlib.IR { - public class InstructionArgumentMeta { - public string name; - public ArgumentMetaFlag flag; - } -} diff --git a/Plugins/dnlib/IR/InstructionMeta.cs b/Plugins/dnlib/IR/InstructionMeta.cs deleted file mode 100644 index 37710aa..0000000 --- a/Plugins/dnlib/IR/InstructionMeta.cs +++ /dev/null @@ -1,412 +0,0 @@ -using System.Collections.Generic; - - -namespace dnlib.IR { - - public enum InstructionFlag { - None = 0, - InlineToken = 0x1, - SideEffect = 0x2, - InlineOffset = 0x4, - } - - public class InstructionMeta { - // family - // opcode - //public IRFamily family; - public readonly List args; - - public readonly InstructionFlag flag; - - public InstructionMeta(InstructionArgumentMeta[] args, InstructionFlag flag) { - this.args = new List(args); - this.flag = flag; - } - - public static InstructionMeta Create(params InstructionArgumentMeta[] args) { - return new InstructionMeta(args, InstructionFlag.None); - } - - public static InstructionMeta Create(InstructionFlag flag, params InstructionArgumentMeta[] args) { - return new InstructionMeta(args, flag); - } - - private readonly static InstructionMeta s_loadorSet = Create( - new InstructionArgumentMeta { name = "dest", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_loadAddress = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.LoadAddress }); - - private readonly static InstructionMeta s_loadConstant = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.Constant } - ); - - private readonly static InstructionMeta s_call = Create(InstructionFlag.SideEffect | InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "ret", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "params", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.Variadic } - ); - - private readonly static InstructionMeta s_newobj = Create(InstructionFlag.SideEffect | InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "ret", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "params", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.Variadic } - ); - - private readonly static InstructionMeta s_ret = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_br = Create(InstructionFlag.InlineOffset, - new InstructionArgumentMeta { name = "params", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.Variadic } - ); - private readonly static InstructionMeta s_condBr = Create(InstructionFlag.InlineOffset, - new InstructionArgumentMeta { name = "params", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.Variadic } - ); - - private readonly static InstructionMeta s_switch = Create(InstructionFlag.InlineOffset, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_compare = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "op1", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "op2", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_loadInd = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.LoadIndirect }); - - private readonly static InstructionMeta s_storeInd = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out | ArgumentMetaFlag.StoreIndirect }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_binOp = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "op1", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "op2", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_unaryOp = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_conv = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_initobj = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.InOut | ArgumentMetaFlag.StoreIndirect } - ); - - private readonly static InstructionMeta s_cpobj = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out | ArgumentMetaFlag.StoreIndirect }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.LoadIndirect } - ); - - private readonly static InstructionMeta s_ldobj = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.LoadIndirect } - ); - - private readonly static InstructionMeta s_stobj = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out | ArgumentMetaFlag.StoreIndirect }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - - ); - - private readonly static InstructionMeta s_castclass = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_isinst = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_box = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_unbox = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_unboxAny = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_throw = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "exObj", flag = ArgumentMetaFlag.In }); - private readonly static InstructionMeta s_rethrow = Create(InstructionFlag.SideEffect); - - private readonly static InstructionMeta s_leave = Create(InstructionFlag.InlineOffset); - - private readonly static InstructionMeta s_endFinallyOrFault = Create(InstructionFlag.SideEffect); - - private readonly static InstructionMeta s_endfilter = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_loadExceptionObj = Create( - new InstructionArgumentMeta { name = "exObj", flag = ArgumentMetaFlag.Out }); - - private readonly static InstructionMeta s_ldfld = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "obj", flag = ArgumentMetaFlag.In } - ); - private readonly static InstructionMeta s_ldflda = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "obj", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_stfld = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "obj", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_ldsfld = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out } - ); - - private readonly static InstructionMeta s_ldsflda = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }); - - private readonly static InstructionMeta s_stsfld = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_newarr = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "size", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_ldlen = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_ldelema = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "address", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "index", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_ldelem = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "index", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_stelem = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "index", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_ldelemAny = Create(InstructionFlag.SideEffect | InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "index", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_stelemAny = Create(InstructionFlag.SideEffect | InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "arr", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "index", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_loadftn = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "method", flag = ArgumentMetaFlag.Out } - ); - - private readonly static InstructionMeta s_ldvirtftn = Create(InstructionFlag.InlineToken | InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "method", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "obj", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_localloc = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "size", flag = ArgumentMetaFlag.In } - ); - - private readonly static InstructionMeta s_initblk = Create( - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.StoreIndirect }, - new InstructionArgumentMeta { name = "value", flag = ArgumentMetaFlag.In }, - new InstructionArgumentMeta { name = "size", flag = ArgumentMetaFlag.In } - ); - private readonly static InstructionMeta s_cpblk = Create( - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out | ArgumentMetaFlag.StoreIndirect }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In | ArgumentMetaFlag.LoadIndirect }, - new InstructionArgumentMeta { name = "size", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_sizeof = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "size", flag = ArgumentMetaFlag.Out }); - - private readonly static InstructionMeta s_mkrefany = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_refanytype = Create( - new InstructionArgumentMeta { name = "type", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_refanyval = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "dst", flag = ArgumentMetaFlag.Out }, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_ckfinite = Create(InstructionFlag.SideEffect, - new InstructionArgumentMeta { name = "src", flag = ArgumentMetaFlag.In }); - - private readonly static InstructionMeta s_ldtoken = Create(InstructionFlag.InlineToken, - new InstructionArgumentMeta { name = "runtimeHandle", flag = ArgumentMetaFlag.Out }); - - - - public static InstructionMeta Get(IROpCode code) { - switch (code) { - case IROpCode.LoadOrSet: return s_loadorSet; - case IROpCode.LoadAddress: return s_loadAddress; - case IROpCode.LoadConstant: return s_loadConstant; - case IROpCode.Call: - case IROpCode.CallVir: - case IROpCode.CallI: return s_call; - case IROpCode.NewObj: return s_newobj; - case IROpCode.Ret: return s_ret; - case IROpCode.UnconditionBranch: return s_br; - case IROpCode.BranchFalse: - case IROpCode.BranchTrue: - case IROpCode.Beq: - case IROpCode.Bge: - case IROpCode.Bgt: - case IROpCode.Ble: - case IROpCode.Blt: - case IROpCode.Bne_Un: - case IROpCode.Bge_Un: - case IROpCode.Bgt_Un: - case IROpCode.Ble_Un: - case IROpCode.Blt_Un: return s_condBr; - case IROpCode.Switch: return s_switch; - case IROpCode.Ceq: - case IROpCode.Cgt: - case IROpCode.Cgt_Un: - case IROpCode.Clt: - case IROpCode.Clt_Un: return s_compare; - case IROpCode.LoadIndirect: return s_loadInd; - case IROpCode.StoreIndirect: return s_storeInd; - case IROpCode.Add: - case IROpCode.Add_Ovf: - case IROpCode.Add_Ovf_Un: - case IROpCode.Sub: - case IROpCode.Sub_Ovf: - case IROpCode.Sub_Ovf_Un: - case IROpCode.Mul: - case IROpCode.Mul_Ovf: - case IROpCode.Mul_Ovf_Un: - case IROpCode.Div: - case IROpCode.Div_Un: - case IROpCode.Rem: - case IROpCode.Rem_Un: - case IROpCode.And: - case IROpCode.Or: - case IROpCode.Xor: - case IROpCode.Shl: - case IROpCode.Shr: - case IROpCode.Shr_Un: return s_binOp; - case IROpCode.Neg: - case IROpCode.Not: return s_unaryOp; - case IROpCode.Conv_I1: - case IROpCode.Conv_I2: - case IROpCode.Conv_I4: - case IROpCode.Conv_I8: - case IROpCode.Conv_U1: - case IROpCode.Conv_U2: - case IROpCode.Conv_U4: - case IROpCode.Conv_U8: - case IROpCode.Conv_I: - case IROpCode.Conv_U: - case IROpCode.Conv_R4: - case IROpCode.Conv_R8: - case IROpCode.Conv_Ovf_I1: - case IROpCode.Conv_Ovf_I2: - case IROpCode.Conv_Ovf_I4: - case IROpCode.Conv_Ovf_I8: - case IROpCode.Conv_Ovf_U1: - case IROpCode.Conv_Ovf_U2: - case IROpCode.Conv_Ovf_U4: - case IROpCode.Conv_Ovf_U8: - case IROpCode.Conv_Ovf_I: - case IROpCode.Conv_Ovf_U: - case IROpCode.Conv_Ovf_I1_Un: - case IROpCode.Conv_Ovf_I2_Un: - case IROpCode.Conv_Ovf_I4_Un: - case IROpCode.Conv_Ovf_I8_Un: - case IROpCode.Conv_Ovf_U1_Un: - case IROpCode.Conv_Ovf_U2_Un: - case IROpCode.Conv_Ovf_U4_Un: - case IROpCode.Conv_Ovf_U8_Un: - case IROpCode.Conv_Ovf_I_Un: - case IROpCode.Conv_Ovf_U_Un: return s_conv; - case IROpCode.InitObj: return s_initobj; - case IROpCode.CpObj: return s_cpobj; - case IROpCode.LdObj: return s_ldobj; - case IROpCode.StObj: return s_stobj; - case IROpCode.CastClass: return s_castclass; - case IROpCode.IsInst: return s_isinst; - case IROpCode.Box: return s_box; - case IROpCode.Unbox: return s_unbox; - case IROpCode.Unbox_Any: return s_unboxAny; - case IROpCode.Throw: return s_throw; - case IROpCode.Rethrow: return s_rethrow; - case IROpCode.Leave: return s_leave; - case IROpCode.EndFinallyOrFault: return s_endFinallyOrFault; - case IROpCode.EndFilter: return s_endfilter; - case IROpCode.LoadExceptionObject: return s_loadExceptionObj; - case IROpCode.Ldfld: return s_ldfld; - case IROpCode.Ldflda: return s_ldflda; - case IROpCode.Stfld: return s_stfld; - case IROpCode.Ldsfld: return s_ldsfld; - case IROpCode.Ldsflda: return s_ldsflda; - case IROpCode.Stsfld: return s_stsfld; - case IROpCode.Newarr: return s_newarr; - case IROpCode.LdLen: return s_ldlen; - case IROpCode.Ldelema: return s_ldelema; - case IROpCode.Ldelem_I1: - case IROpCode.Ldelem_U1: - case IROpCode.Ldelem_I2: - case IROpCode.Ldelem_U2: - case IROpCode.Ldelem_I4: - case IROpCode.Ldelem_U4: - case IROpCode.Ldelem_I8: - case IROpCode.Ldelem_I: - case IROpCode.Ldelem_R4: - case IROpCode.Ldelem_R8: - case IROpCode.Ldelem_Ref: return s_ldelem; - case IROpCode.Stelem_I: - case IROpCode.Stelem_I1: - case IROpCode.Stelem_I2: - case IROpCode.Stelem_I4: - case IROpCode.Stelem_I8: - case IROpCode.Stelem_R4: - case IROpCode.Stelem_R8: - case IROpCode.Stelem_Ref: return s_stelem; - - case IROpCode.Stelem: return s_stelemAny; - case IROpCode.Ldelem: return s_ldelemAny; - case IROpCode.Ldftn: return s_loadftn; - case IROpCode.Ldvirtftn: return s_ldvirtftn; - case IROpCode.Localloc: return s_localloc; - case IROpCode.Initblk: return s_initblk; - case IROpCode.Cpblk: return s_cpblk; - case IROpCode.Sizeof: return s_sizeof; - case IROpCode.Mkrefany: return s_mkrefany; - case IROpCode.Refanytype: return s_refanytype; - case IROpCode.Refanyval: return s_refanyval; - case IROpCode.Ckfinite: return s_ckfinite; - case IROpCode.Ldtoken: return s_ldtoken; - default: throw new System.Exception($"Unknown opcode:{code}"); - } - } - } -} diff --git a/Plugins/dnlib/IR/MethodBasicBlocks.cs b/Plugins/dnlib/IR/MethodBasicBlocks.cs deleted file mode 100644 index 03d259f..0000000 --- a/Plugins/dnlib/IR/MethodBasicBlocks.cs +++ /dev/null @@ -1,93 +0,0 @@ -using System.Collections.Generic; -using System.Linq; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - - -namespace dnlib.IR { - class MethodBasicBlocks { - public List BasicBlocks { get; } - - public Dictionary Inst2BasicBlock { get; } - - public MethodBasicBlocks(List basicBlocks) { - this.BasicBlocks = basicBlocks; - this.Inst2BasicBlock = new Dictionary(); - foreach (var bb in basicBlocks) { - var inst = bb.Instructions[0]; - Inst2BasicBlock[inst] = bb; - } - } - - public BasicBlock GetBasicBlockByInst(Instruction inst) { - if (Inst2BasicBlock.TryGetValue(inst, out var bb)) { - return bb; - } - - return null; - } - - public static MethodBasicBlocks SplitBasicBlocks(MethodDef methodDef) { - var targetInsts = new HashSet(); - bool isEndOfBasicBlock = false; - foreach (var instruction in methodDef.Body.Instructions) { - if (isEndOfBasicBlock) { - targetInsts.Add(instruction); - isEndOfBasicBlock = false; - } - - switch (instruction.OpCode.FlowControl) { - case FlowControl.Branch: - case FlowControl.Cond_Branch: { - if (instruction.Operand is Instruction target) { - targetInsts.Add(target); - isEndOfBasicBlock = true; - } - else if (instruction.Operand is IList targets) { - foreach (var targetInst in targets) { - targetInsts.Add(targetInst); - } - isEndOfBasicBlock = true; - } - - break; - } - case FlowControl.Return: - case FlowControl.Throw: { - isEndOfBasicBlock = true; - break; - } - // case FlowControl.Call: - // { - // targetInsts.Add(instruction); - // break; - // } - } - } - - foreach (var exceptionHandler in methodDef.Body.ExceptionHandlers) { - targetInsts.Add(exceptionHandler.HandlerStart); - targetInsts.Add(exceptionHandler.HandlerEnd); - if (exceptionHandler.FilterStart != null) { - targetInsts.Add(exceptionHandler.FilterStart); - } - - targetInsts.Add(exceptionHandler.TryStart); - targetInsts.Add(exceptionHandler.TryEnd); - } - - BasicBlock currentBasicBlock = null; - var bbs = new List(); - foreach (var instruction in methodDef.Body.Instructions) { - if (currentBasicBlock == null || targetInsts.Contains(instruction)) { - currentBasicBlock = new BasicBlock(); - bbs.Add(currentBasicBlock); - } - currentBasicBlock.AddInstruction(instruction); - } - - - return new MethodBasicBlocks(bbs); - } - } -} diff --git a/Plugins/dnlib/IR/StronglyConnectedComponents.cs b/Plugins/dnlib/IR/StronglyConnectedComponents.cs deleted file mode 100644 index cdb76d1..0000000 --- a/Plugins/dnlib/IR/StronglyConnectedComponents.cs +++ /dev/null @@ -1,60 +0,0 @@ -using System.Collections.Generic; -using System.Diagnostics; - - -namespace dnlib.IR { - class StronglyConnectedComponents { - private readonly HashSet _bbs = new HashSet(); - - private StronglyConnectedComponents _mergeTo; - - private readonly List _inboundSccs = new List(); - private readonly List _outboundSccs = new List(); - - public void AddBlock(IRBasicBlock bb) { - _bbs.Add(bb); - } - - public bool Contains(IRBasicBlock bb) { - return _bbs.Contains(bb); - } - - public void Merge(StronglyConnectedComponents other, Dictionary bb2scc) { - if (other._mergeTo != null) { - Debug.Assert(other._mergeTo == this); - return; - } - other._mergeTo = this; - foreach (var bb in other._bbs) { - if (_bbs.Add(bb)) { - bb2scc[bb] = this; - } - } - } - - public void InitOutboundSccs(Dictionary bb2scc) { - var outboundSccs = new HashSet(); - foreach (var bb in _bbs) { - foreach (var next in bb.OutboundBasicBlocks) { - StronglyConnectedComponents nextScc = bb2scc[next]; - if (nextScc != this) { - outboundSccs.Add(nextScc); - } - } - } - foreach (var scc in outboundSccs) { - _outboundSccs.Add(scc); - scc._inboundSccs.Add(this); - } - } - - public void AddOutboundScc(StronglyConnectedComponents scc) { - if (_outboundSccs.Contains(scc)) { - Debug.Assert(scc._inboundSccs.Contains(this)); - return; - } - _outboundSccs.Add(scc); - scc._inboundSccs.Add(this); - } - } -} diff --git a/Plugins/dnlib/IR/TransformContext.cs b/Plugins/dnlib/IR/TransformContext.cs deleted file mode 100644 index 3b92e3e..0000000 --- a/Plugins/dnlib/IR/TransformContext.cs +++ /dev/null @@ -1,735 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection.Emit; -using dnlib.DotNet; -using dnlib.DotNet.Emit; -using dnlib.Utils; -using ExceptionHandler = dnlib.DotNet.Emit.ExceptionHandler; - - -namespace dnlib.IR { - - public partial class TransformContext { - - private readonly MethodDef _methodDef; - private readonly VariableSet _vs; - private readonly EvalStack _es; - private readonly ParameterList _parameters; - private readonly LocalList _locals; - private readonly ICorLibTypes _corLibTypes; - - public TransformContext(MethodDef methodDef) { - _methodDef = methodDef; - _vs = new VariableSet(_methodDef.Module); - _es = new EvalStack(); - _parameters = methodDef.Parameters; - _locals = methodDef.Body.Variables; - _corLibTypes = methodDef.Module.CorLibTypes; - - _vs.InitParams(_parameters); - _vs.InitLocals(_locals); - } - - public VariableInfo GetParam(Instruction inst) { - return _vs.GetParam(inst.GetParameterIndex()); - } - - public VariableInfo GetLocal(Instruction inst) { - return _vs.GetLocal(inst.GetLocal(_locals).Index); - } - - private void AddInstruction(IRInstruction inst) { - //_methodDef.Body.Instructions.Add(inst); - _curIrbb.AddInstruction(inst); - } - - private void AddLoad(VariableInfo src) { - var dst = _vs.CreateTempVar(src.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.LoadOrSet, IROpCode.LoadOrSet, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - } - - private void AddLoadAddress(VariableInfo src) { - var dst = _vs.CreateTempVar(src.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.LoadAddress, IROpCode.LoadAddress, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - } - - private void AddSet(VariableInfo dst, VariableInfo src) { - var ir = IRInstruction.Create(IRFamily.LoadOrSet, IROpCode.LoadOrSet, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - } - - private void AddSetFromTop(VariableInfo dst) { - AddSet(dst, _es.Pop()); - } - - private void AddLoadConst(TypedConst src) { - var dst = _vs.CreateConstVar(src); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.LoadConstant, IROpCode.LoadConstant, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateConst(src)); - AddInstruction(ir); - } - - //private void AddBranch(IROpCode opCode, int target, params VariableInfo[] parameters) { - // _es.Pop(parameters.Length); - // var ir = IRInstruction.Create(IRFamily.Branch, opCode, InstructionArgument.CreateBranchTarget(target), InstructionArgument.CreateMultiVariable(parameters)); - // AddInstruction(ir); - //} - - private void AddBranch(Instruction il, int paramCount) { - IRBasicBlock target = GetIRBasicBlock((Instruction)il.Operand); - _curIrbb.AddOutboundBasicBlock(target); - VariableInfo[] parameters = _es.PopWithValue(paramCount); - var ir = IRInstruction.Create(IRFamily.Branch, GetBranchIRCodeByILCode(il.OpCode.Code), target, InstructionArgument.CreateMultiVariable(parameters)); - AddInstruction(ir); - _es.SaveInbound(target); - } - - private void AddSwitch(Instruction il) { - var cases = (Instruction[])il.Operand; - var index = _es.Pop(); - var targets = cases.Select(c => GetIRBasicBlock(c)).ToArray(); - foreach (var target in targets) { - _curIrbb.AddOutboundBasicBlock(target); - _es.SaveInbound(target); - } - var ir = IRInstruction.Create(IRFamily.Branch, IROpCode.Switch, targets, InstructionArgument.CreateVariable(index)); - AddInstruction(ir); - } - - private IRBasicBlock GetIRBasicBlock(Instruction inst) { - BasicBlock bb = _bbs.GetBasicBlockByInst(inst); - return _il2irBb[bb]; - } - - - struct MethodReturnTypeAndParams { - public TypeSig returnType; - public List parameterTypes; - } - - struct GenericInst { - public IList typeGenArgs; - public IList methodGenArgs; - } - - private GenericInst ResolveGenericContenxt(IMethod method) { - IList typeGenArgs = null; - IList methodGenArgs = null; - if (method is MemberRef memberRef) { - var parent = memberRef.Class; - if (parent is TypeSpec) { - if (((TypeSpec)parent).TypeSig is GenericInstSig sig) - typeGenArgs = sig.GenericArguments; - } - } - else if (method is MethodSpec methodSpec) { - if (methodSpec.Method is MemberRef mr) { - var parent = mr.Class; - if (parent is TypeSpec) { - if (((TypeSpec)parent).TypeSig is GenericInstSig sig) - typeGenArgs = sig.GenericArguments; - } - } - methodGenArgs = methodSpec.GenericInstMethodSig?.GenericArguments; - } - return new GenericInst { - typeGenArgs = typeGenArgs, - methodGenArgs = methodGenArgs, - }; - } - - private GenericInst ResolveGenericContenxt(IField field) { - IList typeGenArgs = null; - if (field is MemberRef memberRef) { - var parent = memberRef.Class; - if (parent is TypeSpec) { - if (((TypeSpec)parent).TypeSig is GenericInstSig sig) - typeGenArgs = sig.GenericArguments; - } - } - return new GenericInst { - typeGenArgs = typeGenArgs, - methodGenArgs = null, - }; - } - - MethodReturnTypeAndParams MakeMethodFinalSignature(MethodSig methodSig, IList typeGenArgs, IList methodGenArgs) { - var ga = new GenericArguments(); - if (typeGenArgs is not null) - ga.PushTypeArgs(typeGenArgs); - if (methodGenArgs is not null) - ga.PushMethodArgs(methodGenArgs); - var returnType = ga.Resolve(methodSig.RetType); - var parameterTypes = methodSig.Params.Select(p => ga.Resolve(p)).ToList(); - if (methodSig.HasThis) - parameterTypes.Insert(0, _corLibTypes.UInt32); - return new MethodReturnTypeAndParams { - returnType = returnType, - parameterTypes = parameterTypes, - }; - } - - TypeSig MakeFieldFinalType(TypeSig type, IList typeGenArgs) { - var ga = new GenericArguments(); - if (typeGenArgs is not null) - ga.PushTypeArgs(typeGenArgs); - var returnType = ga.Resolve(type); - return returnType; - } - - TypeSig GetFieldType(IField field) { - var typeGenArgs = ResolveGenericContenxt(field).typeGenArgs; - return MakeFieldFinalType(field.FieldSig.Type, typeGenArgs); - } - - - private void AddCall(IROpCode opCode, IMethod method, PrefixData? prefixData) { - - MethodSig methodSig = method.MethodSig; - - var mgc = ResolveGenericContenxt(method); - var mrtp = MakeMethodFinalSignature(methodSig, mgc.typeGenArgs, mgc.methodGenArgs); - - - - - AddCall(opCode, method, mrtp.returnType, mrtp.parameterTypes.ToArray(), prefixData); - //int paramCount = method.MethodSig.Params.Count + (method.MethodSig.HasThis ? 1 : 0); - //VariableInfo[] parameters = _es.PopWithValue(paramCount); - //VariableInfo ret; - //if (method.MethodSig.RetType.ElementType == ElementType.Void) { - // ret = null; - //} else { - // ret = _vs.CreateTempVar(method.MethodSig.RetType); - // _es.Push(ret); - //} - //var ir = Instruction.Create(IRFamily.Call, IROpCode.Call, ret != null ? InstructionArgument.CreateVariable(ret) : null, InstructionArgument.CreateMultiVariable(parameters)); - //AddInstruction(ir); - } - - private void AddCall(IROpCode opCode, object token, TypeSig returnType, TypeSig[] parameterTypes, PrefixData? prefixData) { - int paramCount = parameterTypes?.Length ?? 0; - VariableInfo[] parameters = _es.PopWithValue(paramCount); - VariableInfo ret; - if (returnType.ElementType == ElementType.Void) { - ret = null; - } - else { - ret = _vs.CreateTempVar(returnType); - _es.Push(ret); - } - var ir = IRInstruction.Create(IRFamily.Call, opCode, prefixData, ret != null ? InstructionArgument.CreateVariable(ret) : null, InstructionArgument.CreateMultiVariable(parameters)); - ir.inlineOperand = token; - AddInstruction(ir); - } - - private void AddNewObj(IMethod methodInfo) { - MethodSig method = methodInfo.MethodSig; - int paramCount = method.Params.Count; - VariableInfo[] parameters = _es.PopWithValue(paramCount); - VariableInfo ret = _vs.CreateTempVar(method.RetType); - _es.Push(ret); - - var ir = IRInstruction.Create(IRFamily.Call, IROpCode.NewObj, ret != null ? InstructionArgument.CreateVariable(ret) : null, InstructionArgument.CreateMultiVariable(parameters)); - ir.inlineOperand = methodInfo; - AddInstruction(ir); - } - - private TypeSig CalcEqualType(TypeSig type) { - if (type.IsByRef) { - return _corLibTypes.IntPtr; - } - switch (type.ElementType) { - case ElementType.Boolean: - case ElementType.Char: - case ElementType.I1: - case ElementType.U1: - case ElementType.I2: - case ElementType.U2: - case ElementType.I4: - case ElementType.U4: return _corLibTypes.Int32; - case ElementType.I8: - case ElementType.U8: return _corLibTypes.Int64; - case ElementType.R4: return _corLibTypes.Single; - case ElementType.R8: return _corLibTypes.Double; - case ElementType.I: - case ElementType.U: - case ElementType.Ptr: - case ElementType.FnPtr: - case ElementType.Object: - return _corLibTypes.IntPtr; - default: return type; - } - } - - private TypeSig CalcConvertResultType(Code code) { - switch (code) { - case Code.Conv_I1: - case Code.Conv_I2: - case Code.Conv_I4: - case Code.Conv_U1: - case Code.Conv_U2: - case Code.Conv_U4: - case Code.Conv_Ovf_I1: - case Code.Conv_Ovf_I2: - case Code.Conv_Ovf_I4: - case Code.Conv_Ovf_U1: - case Code.Conv_Ovf_U2: - case Code.Conv_Ovf_U4: - case Code.Conv_Ovf_I1_Un: - case Code.Conv_Ovf_I2_Un: - case Code.Conv_Ovf_I4_Un: - case Code.Conv_Ovf_U1_Un: - case Code.Conv_Ovf_U2_Un: - case Code.Conv_Ovf_U4_Un: return _corLibTypes.Int32; - case Code.Conv_I8: - case Code.Conv_U8: - case Code.Conv_Ovf_I8: - case Code.Conv_Ovf_U8: - case Code.Conv_Ovf_I8_Un: - case Code.Conv_Ovf_U8_Un: return _corLibTypes.Int64; - case Code.Conv_I: - case Code.Conv_U: - case Code.Conv_Ovf_I: - case Code.Conv_Ovf_U: - case Code.Conv_Ovf_I_Un: - case Code.Conv_Ovf_U_Un: return _corLibTypes.IntPtr; - case Code.Conv_R4: return _corLibTypes.Single; - case Code.Conv_R8: return _corLibTypes.Double; - default: throw new NotSupportedException(); - } - } - - private TypeSig CalcArithOpResultType(TypeSig op1, TypeSig op2) { - - // int32 + int32 = int32 - // int32 + native int => native int - // x + int64 => int64 - // enum + x => enum - var type1 = CalcEqualType(op1).ElementType; - var type2 = CalcEqualType(op2).ElementType; - - if (type1 == ElementType.ValueType || type1 == ElementType.GenericInst) { - switch (type2) { - case ElementType.I4: - case ElementType.I8: - case ElementType.I: return op1; - default: throw new NotSupportedException(); - } - } - else if (type2 == ElementType.ValueType || type2 == ElementType.GenericInst) { - switch (type1) { - case ElementType.I4: - case ElementType.I8: - case ElementType.I: return op2; - default: throw new NotSupportedException(); - } - } - - switch (type1) { - case ElementType.I4: { - switch (type2) { - case ElementType.I4: return _corLibTypes.Int32; - case ElementType.I8: return _corLibTypes.Int64; - case ElementType.I: return _corLibTypes.IntPtr; - default: throw new NotSupportedException(); - } - } - case ElementType.I8: { - switch (type2) { - case ElementType.I4: - case ElementType.I8: - case ElementType.I: return _corLibTypes.Int64; - default: throw new NotSupportedException(); - } - } - case ElementType.I: { - switch (type2) { - case ElementType.I4: - case ElementType.I: return _corLibTypes.IntPtr; - case ElementType.I8: return _corLibTypes.Int64; - default: throw new NotSupportedException(); - } - } - case ElementType.R4: { - switch (type2) { - case ElementType.R4: return _corLibTypes.Single; - case ElementType.R8: return _corLibTypes.Double; - default: throw new NotSupportedException(); - } - } - case ElementType.R8: { - switch (type2) { - case ElementType.R4: - case ElementType.R8: return _corLibTypes.Double; - default: throw new NotSupportedException(); - } - } - default: throw new NotSupportedException(); - } - } - - private IROpCode GetArithIROpcodeByILCode(Code code) { - switch (code) { - case Code.Add: return IROpCode.Add; - case Code.Add_Ovf: return IROpCode.Add_Ovf; - case Code.Add_Ovf_Un: return IROpCode.Add_Ovf_Un; - case Code.Sub: return IROpCode.Sub; - case Code.Sub_Ovf: return IROpCode.Sub_Ovf; - case Code.Sub_Ovf_Un: return IROpCode.Sub_Ovf_Un; - case Code.Mul: return IROpCode.Mul; - case Code.Mul_Ovf: return IROpCode.Mul_Ovf; - case Code.Mul_Ovf_Un: return IROpCode.Mul_Ovf_Un; - case Code.Div: return IROpCode.Div; - case Code.Div_Un: return IROpCode.Div_Un; - case Code.Rem: return IROpCode.Rem; - case Code.Rem_Un: return IROpCode.Rem_Un; - case Code.And: return IROpCode.And; - case Code.Or: return IROpCode.Or; - case Code.Xor: return IROpCode.Xor; - case Code.Shl: return IROpCode.Shl; - case Code.Shr: return IROpCode.Shr; - case Code.Shr_Un: return IROpCode.Shr_Un; - default: throw new NotSupportedException(); - } - } - - private IROpCode GetConvertIROpcodeByILCode(Code code) { - switch (code) { - case Code.Conv_I1: return IROpCode.Conv_I1; - case Code.Conv_I2: return IROpCode.Conv_I2; - case Code.Conv_I4: return IROpCode.Conv_I4; - case Code.Conv_I8: return IROpCode.Conv_I8; - case Code.Conv_U1: return IROpCode.Conv_U1; - case Code.Conv_U2: return IROpCode.Conv_U2; - case Code.Conv_U4: return IROpCode.Conv_U4; - case Code.Conv_U8: return IROpCode.Conv_U8; - case Code.Conv_I: return IROpCode.Conv_I; - case Code.Conv_U: return IROpCode.Conv_U; - case Code.Conv_R4: return IROpCode.Conv_R4; - case Code.Conv_R8: return IROpCode.Conv_R8; - case Code.Conv_Ovf_I1: return IROpCode.Conv_Ovf_I1; - case Code.Conv_Ovf_I2: return IROpCode.Conv_Ovf_I2; - case Code.Conv_Ovf_I4: return IROpCode.Conv_Ovf_I4; - case Code.Conv_Ovf_I8: return IROpCode.Conv_Ovf_I8; - case Code.Conv_Ovf_U1: return IROpCode.Conv_Ovf_U1; - case Code.Conv_Ovf_U2: return IROpCode.Conv_Ovf_U2; - case Code.Conv_Ovf_U4: return IROpCode.Conv_Ovf_U4; - case Code.Conv_Ovf_U8: return IROpCode.Conv_Ovf_U8; - case Code.Conv_Ovf_I: return IROpCode.Conv_Ovf_I; - case Code.Conv_Ovf_U: return IROpCode.Conv_Ovf_U; - case Code.Conv_Ovf_I1_Un: return IROpCode.Conv_Ovf_I1_Un; - case Code.Conv_Ovf_I2_Un: return IROpCode.Conv_Ovf_I2_Un; - case Code.Conv_Ovf_I4_Un: return IROpCode.Conv_Ovf_I4_Un; - case Code.Conv_Ovf_I8_Un: return IROpCode.Conv_Ovf_I8_Un; - case Code.Conv_Ovf_U1_Un: return IROpCode.Conv_Ovf_U1_Un; - case Code.Conv_Ovf_U2_Un: return IROpCode.Conv_Ovf_U2_Un; - case Code.Conv_Ovf_U4_Un: return IROpCode.Conv_Ovf_U4_Un; - case Code.Conv_Ovf_U8_Un: return IROpCode.Conv_Ovf_U8_Un; - case Code.Conv_Ovf_I_Un: return IROpCode.Conv_Ovf_I_Un; - case Code.Conv_Ovf_U_Un: return IROpCode.Conv_Ovf_U_Un; - default: throw new NotSupportedException(); - } - } - - private IROpCode GetArrayIROpcodeByILCode(Code code) { - switch (code) { - case Code.Newarr: return IROpCode.Newarr; - case Code.Ldlen: return IROpCode.LdLen; - case Code.Ldelema: return IROpCode.Ldelema; - case Code.Ldelem_I1: return IROpCode.Ldelem_I1; - case Code.Ldelem_U1: return IROpCode.Ldelem_U1; - case Code.Ldelem_I2: return IROpCode.Ldelem_I2; - case Code.Ldelem_U2: return IROpCode.Ldelem_U2; - case Code.Ldelem_I4: return IROpCode.Ldelem_I4; - case Code.Ldelem_U4: return IROpCode.Ldelem_U4; - case Code.Ldelem_I8: return IROpCode.Ldelem_I8; - case Code.Ldelem_I: return IROpCode.Ldelem_I; - case Code.Ldelem_R4: return IROpCode.Ldelem_R4; - case Code.Ldelem_R8: return IROpCode.Ldelem_R8; - case Code.Ldelem_Ref: return IROpCode.Ldelem_Ref; - case Code.Stelem_I: return IROpCode.Stelem_I; - case Code.Stelem_I1: return IROpCode.Stelem_I1; - case Code.Stelem_I2: return IROpCode.Stelem_I2; - case Code.Stelem_I4: return IROpCode.Stelem_I4; - case Code.Stelem_I8: return IROpCode.Stelem_I8; - case Code.Stelem_R4: return IROpCode.Stelem_R4; - case Code.Stelem_R8: return IROpCode.Stelem_R8; - case Code.Stelem_Ref: return IROpCode.Stelem_Ref; - case Code.Ldelem: return IROpCode.Ldelem; - case Code.Stelem: return IROpCode.Stelem; - default: throw new NotSupportedException(); - } - } - - private IROpCode GetBranchIRCodeByILCode(Code code) { - switch (code) { - case Code.Brfalse: - case Code.Brfalse_S: return IROpCode.BranchFalse; - case Code.Brtrue: - case Code.Brtrue_S: return IROpCode.BranchTrue; - case Code.Br: - case Code.Br_S: return IROpCode.UnconditionBranch; - case Code.Beq: - case Code.Beq_S: return IROpCode.Beq; - case Code.Bge: - case Code.Bge_S: return IROpCode.Bge; - case Code.Bgt: - case Code.Bgt_S: return IROpCode.Bgt; - case Code.Ble: - case Code.Ble_S: return IROpCode.Ble; - case Code.Blt: - case Code.Blt_S: return IROpCode.Blt; - case Code.Bne_Un: - case Code.Bne_Un_S: return IROpCode.Bne_Un; - case Code.Bge_Un: - case Code.Bge_Un_S: return IROpCode.Bge_Un; - case Code.Bgt_Un: - case Code.Bgt_Un_S: return IROpCode.Bgt_Un; - case Code.Ble_Un: - case Code.Ble_Un_S: return IROpCode.Ble_Un; - case Code.Blt_Un: - case Code.Blt_Un_S: return IROpCode.Blt_Un; - default: throw new NotSupportedException($"{code}"); - } - } - - private IROpCode GetCompareIRCodeByILCode(Code code) { - switch (code) { - case Code.Ceq: return IROpCode.Ceq; - case Code.Cgt: return IROpCode.Cgt; - case Code.Cgt_Un: return IROpCode.Cgt_Un; - case Code.Clt: return IROpCode.Clt; - case Code.Clt_Un: return IROpCode.Clt_Un; - default: throw new NotSupportedException($"{code}"); - } - } - - private IROpCode GetUnaryIRCodeByILCode(Code code) { - switch (code) { - case Code.Neg: return IROpCode.Neg; - case Code.Not: return IROpCode.Not; - default: throw new NotSupportedException($"{code}"); - } - } - - private IROpCode GetCallIRCodeByILCode(Code code) { - switch (code) { - case Code.Call: return IROpCode.Call; - case Code.Calli: return IROpCode.CallI; - case Code.Callvirt: return IROpCode.CallVir; - default: throw new NotSupportedException($"{code}"); - } - } - - private IROpCode GetUnspecIRCodeByILCode(Code code) { - switch (code) { - case Code.Ldftn: return IROpCode.Ldftn; - case Code.Ldvirtftn: return IROpCode.Ldvirtftn; - default: throw new NotSupportedException($"{code}"); - } - } - - - private readonly Queue _pendingBBs = new Queue(); - - - private IRBasicBlock _curIrbb; - - private MethodBasicBlocks _bbs; - - private Dictionary _il2irBb; - - private List _irbbs; - - - private IRBasicBlock GetIRBasicBlockByIL(Instruction inst) { - return inst != null ? _il2irBb[_bbs.GetBasicBlockByInst(inst)] : null; - } - - - private void SetupExceptionHandlerStart(Instruction handlerStartInst) { - var bb = _bbs.GetBasicBlockByInst(handlerStartInst); - var irbb = _il2irBb[bb]; - var exceptionObj = _vs.CreateTempVar(_corLibTypes.Object); - irbb.SetInboundVariable(exceptionObj); - irbb.AddInstruction(IRInstruction.Create(IRFamily.Exception, IROpCode.LoadExceptionObject, InstructionArgument.CreateVariable(exceptionObj))); - } - - public IRMethodBody Transform() { - - _bbs = MethodBasicBlocks.SplitBasicBlocks(_methodDef); - - var visitedBBs = new HashSet(); - - _il2irBb = new Dictionary(); - _irbbs = new List(); - IRBasicBlock lastIrbb = null; - foreach (var bb in _bbs.BasicBlocks) { - - IRBasicBlock irbb = new IRBasicBlock { ilbb = bb }; - if (lastIrbb != null) { - lastIrbb.nextIrbb = irbb; - } - _irbbs.Add(irbb); - _il2irBb[bb] = irbb; - - lastIrbb = irbb; - } - - // while enter catch or filter block, push current exception object to exception object stack. - // the first instruction push top exception object to the eval stack. - foreach (var exceptionHandler in _methodDef.Body.ExceptionHandlers) { - - if (exceptionHandler.HandlerStart != null) { - SetupExceptionHandlerStart(exceptionHandler.HandlerStart); - } - if (exceptionHandler.FilterStart != null) { - SetupExceptionHandlerStart(exceptionHandler.FilterStart); - } - - } - - _curIrbb = _irbbs[0]; - - BasicBlock curBb; - for (int nextBasicBlockIndex = 0; ; ) { - while (true) { - if (_pendingBBs.Count > 0) { - curBb = _pendingBBs.Dequeue(); - } - else { - if (nextBasicBlockIndex >= _bbs.BasicBlocks.Count) { - curBb = null; - break; - } - curBb = _bbs.BasicBlocks[nextBasicBlockIndex++]; - } - if (!visitedBBs.Contains(curBb)) { - break; - } - } - if (curBb == null) { - break; - } - visitedBBs.Add(curBb); - TransformBasicBlock(curBb, _il2irBb[curBb]); - } - - var varMapper = new Dictionary(); - MergeInboundOutboundVariables(_irbbs, varMapper); - MapVariableToMergedVariable(_irbbs, varMapper); - - - var irExs = new List(); - foreach (ExceptionHandler exceptionHandler in _methodDef.Body.ExceptionHandlers) { - var irex = new IRExceptionHandler { - TryStart = GetIRBasicBlockByIL(exceptionHandler.TryStart), - TryEnd = GetIRBasicBlockByIL(exceptionHandler.TryEnd), - FilterStart = GetIRBasicBlockByIL(exceptionHandler.FilterStart), - HandlerStart = GetIRBasicBlockByIL(exceptionHandler.HandlerStart), - HandlerEnd = GetIRBasicBlockByIL(exceptionHandler.HandlerEnd), - CatchType = exceptionHandler.CatchType, - HandlerType = exceptionHandler.HandlerType, - }; - irExs.Add(irex); - } - - var irMethod = new IRMethodBody(_methodDef, irExs, _vs, _irbbs); - irMethod.ApplyOptimizations(); - return irMethod; - } - - - private void MapVariableToMergedVariable(List bbs, Dictionary variableMapper) { - foreach (var bb in bbs) { - foreach (var inst in bb.Instructions) { - foreach (InstructionArgument arg in inst.args) { - if (arg is InstructionArgumentVariable varArg) { - if (variableMapper.TryGetValue(varArg.value, out var value)) { - varArg.value = value; - } - } - } - } - } - } - - - private class VariableGroup { - public readonly List variables = new List(); - - public void Add(VariableInfo variable) { - variables.Add(variable); - } - - public void Merge(VariableGroup group, Dictionary variableGroups) { - VariableGroup srcGroup; - VariableGroup dstGroup; - if (group.variables.Count < variables.Count) { - srcGroup = group; - dstGroup = this; - } else { - srcGroup = this; - dstGroup = group; - } - - foreach (var variable in srcGroup.variables) { - dstGroup.variables.Add(variable); - variableGroups[variable] = dstGroup; - } - } - } - - private void MergeInboundOutboundVariables(List bbs, Dictionary variableMapper) { - var visited = new HashSet(); - - var variableGroups = new Dictionary(); - foreach (var bb in bbs) { - MergeInboundOutboundVariables(bb, visited, variableGroups); - } - foreach (var e in variableGroups) { - variableMapper.Add(e.Key, e.Value.variables[0]); - } - } - - private void MergeInboundOutboundVariables(IRBasicBlock bb, HashSet visited, Dictionary variableGroups) { - if (!visited.Add(bb)) { - return; - } - - var outboundVars = bb.OutboundVariables; - foreach (var ov in outboundVars) { - if (!variableGroups.ContainsKey(ov)) { - var group = new VariableGroup(); - variableGroups.Add(ov, group); - group.Add(ov); - } - } - int outBoundVarCount = outboundVars.Count; - foreach (var target in bb.OutboundBasicBlocks) { - if (target.InboundVariables.Count != outBoundVarCount) { - throw new Exception($"method:{_methodDef} InboundVariables.Count != outboundVars.Count"); - } - for (int i = 0; i < outBoundVarCount; i++) { - var ov = outboundVars[i]; - var iv = target.InboundVariables[i]; - var ovGroup = variableGroups[ov]; - if (!variableGroups.TryGetValue(iv, out var ivGroup)) { - ovGroup.Add(iv); - } else if (ivGroup != ovGroup) { - ovGroup.Merge(ivGroup, variableGroups); - } - } - } - foreach (var target in bb.OutboundBasicBlocks) { - MergeInboundOutboundVariables(target, visited, variableGroups); - } - } - } -} diff --git a/Plugins/dnlib/IR/TransformContext_TransformBasicBlock.cs b/Plugins/dnlib/IR/TransformContext_TransformBasicBlock.cs deleted file mode 100644 index a16cce4..0000000 --- a/Plugins/dnlib/IR/TransformContext_TransformBasicBlock.cs +++ /dev/null @@ -1,695 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace dnlib.IR { - - public partial class TransformContext { - - private void TransformBasicBlock(BasicBlock bb, IRBasicBlock irbb) { - _curIrbb = irbb; - _es.LoadInbound(irbb); - PrefixData? prefixData = null; - foreach (var il in bb.Instructions) { - //Console.WriteLine($"IL: {il.OpCode} {il.Operand}"); - Code code = il.OpCode.Code; - switch (code) { - case Code.Nop: break; - case Code.Break: break; - case Code.Ldarg_0: - case Code.Ldarg_1: - case Code.Ldarg_2: - case Code.Ldarg_3: - case Code.Ldarg_S: - case Code.Ldarg: { - var src = GetParam(il); - AddLoad(src); - break; - } - case Code.Ldarga_S: - case Code.Ldarga: { - var src = GetParam(il); - AddLoadAddress(src); - break; - } - case Code.Starg_S: - case Code.Starg: { - var dst = GetParam(il); - AddSetFromTop(dst); - break; - } - case Code.Ldloc_0: - case Code.Ldloc_1: - case Code.Ldloc_2: - case Code.Ldloc_3: - case Code.Ldloc_S: - case Code.Ldloc: { - var src = GetLocal(il); - AddLoad(src); - break; - } - case Code.Ldloca: - case Code.Ldloca_S: { - AddLoadAddress(GetLocal(il)); - break; - } - case Code.Stloc_0: - case Code.Stloc_1: - case Code.Stloc_2: - case Code.Stloc_3: - case Code.Stloc_S: - case Code.Stloc: { - AddSetFromTop(GetLocal(il)); - break; - } - case Code.Ldnull: { - var src = TypedConst.CreateNull(); - AddLoadConst(src); - break; - } - case Code.Ldc_I4_M1: - case Code.Ldc_I4_0: - case Code.Ldc_I4_1: - case Code.Ldc_I4_2: - case Code.Ldc_I4_3: - case Code.Ldc_I4_4: - case Code.Ldc_I4_5: - case Code.Ldc_I4_6: - case Code.Ldc_I4_7: - case Code.Ldc_I4_8: - case Code.Ldc_I4_S: - case Code.Ldc_I4: { - var src = TypedConst.CreateInt(il.GetLdcI4Value()); - AddLoadConst(src); - break; - } - case Code.Ldc_I8: { - var src = TypedConst.CreateLong((long)il.Operand); - AddLoadConst(src); - break; - } - case Code.Ldc_R4: { - var src = TypedConst.CreateFloat((float)il.Operand); - AddLoadConst(src); - break; - } - case Code.Ldc_R8: { - var src = TypedConst.CreateDouble((double)il.Operand); - AddLoadConst(src); - break; - } - case Code.Ldstr: { - var src = TypedConst.CreateString((string)il.Operand); - AddLoadConst(src); - break; - } - case Code.Dup: { - var src = _es.GetTop(); - AddLoad(src); - break; - } - case Code.Pop: { - _es.Pop(); - break; - } - case Code.Ret: { - VariableInfo ret = _methodDef.ReturnType.ElementType == ElementType.Void ? null : _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Ret, IROpCode.Ret, ret != null ? InstructionArgument.CreateVariable(ret) : null); - AddInstruction(ir); - break; - } - case Code.Br_S: - case Code.Br: { - AddBranch(il, 0); - break; - } - case Code.Brfalse_S: - case Code.Brfalse: - case Code.Brtrue_S: - case Code.Brtrue: { - AddBranch(il, 1); - break; - } - case Code.Beq: - case Code.Beq_S: - case Code.Bge: - case Code.Bge_S: - case Code.Bgt: - case Code.Bgt_S: - case Code.Ble: - case Code.Ble_S: - case Code.Blt: - case Code.Blt_S: - case Code.Bne_Un: - case Code.Bne_Un_S: - case Code.Bge_Un: - case Code.Bge_Un_S: - case Code.Bgt_Un: - case Code.Bgt_Un_S: - case Code.Ble_Un: - case Code.Ble_Un_S: - case Code.Blt_Un: - case Code.Blt_Un_S: { - AddBranch(il, 2); - break; - } - case Code.Switch: { - AddSwitch(il); - break; - } - case Code.Ldind_I1: - case Code.Ldind_U1: - case Code.Ldind_I2: - case Code.Ldind_U2: - case Code.Ldind_I4: - case Code.Ldind_U4: - case Code.Ldind_I8: - case Code.Ldind_I: - case Code.Ldind_R4: - case Code.Ldind_R8: - case Code.Ldind_Ref: { - var src = _es.Pop(); - var dst = _vs.CreateTempVar(src.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.LoadIndirect, IROpCode.LoadIndirect, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Stind_I1: - case Code.Stind_I2: - case Code.Stind_I4: - case Code.Stind_I8: - case Code.Stind_I: - case Code.Stind_R4: - case Code.Stind_R8: - case Code.Stind_Ref: { - var src = _es.Pop(); - var dst = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.StoreIndirect, IROpCode.StoreIndirect, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Add: - case Code.Add_Ovf: - case Code.Add_Ovf_Un: - case Code.Sub: - case Code.Sub_Ovf: - case Code.Sub_Ovf_Un: - case Code.Mul: - case Code.Mul_Ovf: - case Code.Mul_Ovf_Un: - case Code.Div: - case Code.Div_Un: - case Code.Rem: - case Code.Rem_Un: - case Code.And: - case Code.Or: - case Code.Xor: { - var op2 = _es.Pop(); - var op1 = _es.Pop(); - var dst = _vs.CreateTempVar(CalcArithOpResultType(op1.type, op2.type)); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.BinOp, GetArithIROpcodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(op1), InstructionArgument.CreateVariable(op2)); - AddInstruction(ir); - break; - } - case Code.Shl: - case Code.Shr: - case Code.Shr_Un: { - var op2 = _es.Pop(); - var op1 = _es.Pop(); - var dst = _vs.CreateTempVar(op1.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.BinOp, GetArithIROpcodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(op1), InstructionArgument.CreateVariable(op2)); - AddInstruction(ir); - break; - } - case Code.Neg: - case Code.Not: { - var op1 = _es.Pop(); - var dst = _vs.CreateTempVar(op1.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.UnOp, GetUnaryIRCodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(op1)); - AddInstruction(ir); - break; - } - case Code.Conv_I1: - case Code.Conv_I2: - case Code.Conv_I4: - case Code.Conv_I8: - case Code.Conv_U1: - case Code.Conv_U2: - case Code.Conv_U4: - case Code.Conv_U8: - case Code.Conv_I: - case Code.Conv_U: - case Code.Conv_R4: - case Code.Conv_R8: - case Code.Conv_R_Un: - case Code.Conv_Ovf_I1: - case Code.Conv_Ovf_I2: - case Code.Conv_Ovf_I4: - case Code.Conv_Ovf_I8: - case Code.Conv_Ovf_U1: - case Code.Conv_Ovf_U2: - case Code.Conv_Ovf_U4: - case Code.Conv_Ovf_U8: - case Code.Conv_Ovf_I: - case Code.Conv_Ovf_U: - case Code.Conv_Ovf_I1_Un: - case Code.Conv_Ovf_I2_Un: - case Code.Conv_Ovf_I4_Un: - case Code.Conv_Ovf_I8_Un: - case Code.Conv_Ovf_U1_Un: - case Code.Conv_Ovf_U2_Un: - case Code.Conv_Ovf_U4_Un: - case Code.Conv_Ovf_U8_Un: - case Code.Conv_Ovf_I_Un: - case Code.Conv_Ovf_U_Un: { - var op1 = _es.Pop(); - var dst = _vs.CreateTempVar(CalcConvertResultType(code)); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Conv, GetConvertIROpcodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(op1)); - AddInstruction(ir); - break; - } - case Code.Cpobj: { - var src = _es.Pop(); - var dst = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Obj, IROpCode.CpObj, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Initobj: { - var src = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Obj, IROpCode.InitObj, InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Ldobj: { - var src = _es.Pop(); - var dst = _vs.CreateTempVar(src.type); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Obj, IROpCode.LdObj, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Stobj: { - var src = _es.Pop(); - var dst = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Obj, IROpCode.StObj, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Call: - case Code.Callvirt: { - IMethod callMethod = (IMethod)il.Operand; - AddCall(GetCallIRCodeByILCode(code), callMethod, prefixData); - break; - } - case Code.Calli: { - MethodSig callMethodSig = (MethodSig)il.Operand; - AddCall(IROpCode.CallI, il.Operand, callMethodSig.RetType, callMethodSig.Params.ToArray(), prefixData); - break; - } - case Code.Newobj: { - IMethod callMethod = (IMethod)il.Operand; - AddNewObj(callMethod); - break; - } - case Code.Castclass: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Object); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Cast, IROpCode.CastClass, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Isinst: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Int32); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Cast, IROpCode.IsInst, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Box: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Object); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Box, IROpCode.Box, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Unbox: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(klass.ToTypeSig()); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Box, IROpCode.Unbox, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Unbox_Any: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.IntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Box, IROpCode.Unbox_Any, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Throw: { - var src = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Exception, IROpCode.Throw, InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - _es.Clear(); - break; - } - case Code.Rethrow: { - var ir = IRInstruction.Create(IRFamily.Exception, IROpCode.Rethrow); - AddInstruction(ir); - _es.Clear(); - break; - } - case Code.Leave: - case Code.Leave_S: { - IRBasicBlock target = GetIRBasicBlock((Instruction)il.Operand); - _curIrbb.AddOutboundBasicBlock(target); - var ir = IRInstruction.Create(IRFamily.Exception, IROpCode.Leave, target); - AddInstruction(ir); - _es.Clear(); - break; - } - case Code.Endfilter: { - var value = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Exception, IROpCode.EndFilter, InstructionArgument.CreateVariable(value)); - AddInstruction(ir); - break; - } - case Code.Endfinally: { - var ir = IRInstruction.Create(IRFamily.Exception, IROpCode.EndFinallyOrFault); - AddInstruction(ir); - _es.Clear(); - break; - } - case Code.Ldfld: { - var field = (IField)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(GetFieldType(field)); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Ldfld, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Ldflda: { - var field = (IField)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.IntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Ldflda, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Stfld: { - var field = (IField)il.Operand; - var src = _es.Pop(); - var dst = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Stfld, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Ldsfld: { - var field = (IField)il.Operand; - var dst = _vs.CreateTempVar(GetFieldType(field)); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Ldsfld, InstructionArgument.CreateVariable(dst)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Ldsflda: { - var field = (IField)il.Operand; - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Ldsflda, InstructionArgument.CreateVariable(dst)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Stsfld: { - var field = (IField)il.Operand; - var src = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Field, IROpCode.Stsfld, InstructionArgument.CreateVariable(src)); - ir.inlineOperand = field; - AddInstruction(ir); - break; - } - case Code.Newarr: { - var klass = (ITypeDefOrRef)il.Operand; - var size = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Object); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Array, IROpCode.Newarr, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(size)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Ldlen: { - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Array, IROpCode.LdLen, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Ldelema: { - var index = _es.Pop(); - var arr = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Array, IROpCode.Ldelema, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(arr), InstructionArgument.CreateVariable(index)); - AddInstruction(ir); - break; - } - case Code.Ldelem_I1: - case Code.Ldelem_U1: - case Code.Ldelem_I2: - case Code.Ldelem_U2: - case Code.Ldelem_I4: - case Code.Ldelem_U4: - case Code.Ldelem_I8: - case Code.Ldelem_I: - case Code.Ldelem_R4: - case Code.Ldelem_R8: - case Code.Ldelem_Ref: { - var index = _es.Pop(); - var arr = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Object); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Array, GetArrayIROpcodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(arr), InstructionArgument.CreateVariable(index)); - AddInstruction(ir); - break; - } - case Code.Stelem_I: - case Code.Stelem_I1: - case Code.Stelem_I2: - case Code.Stelem_I4: - case Code.Stelem_I8: - case Code.Stelem_R4: - case Code.Stelem_R8: - case Code.Stelem_Ref: { - var value = _es.Pop(); - var index = _es.Pop(); - var arr = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Array, GetArrayIROpcodeByILCode(code), InstructionArgument.CreateVariable(arr), InstructionArgument.CreateVariable(index), InstructionArgument.CreateVariable(value)); - AddInstruction(ir); - break; - } - case Code.Ldelem: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var index = _es.Pop(); - var arr = _es.Pop(); - var dst = _vs.CreateTempVar(klass.ToTypeSig()); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Array, GetArrayIROpcodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(arr), InstructionArgument.CreateVariable(index)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Stelem: { - ITypeDefOrRef klass = (ITypeDefOrRef)il.Operand; - var value = _es.Pop(); - var index = _es.Pop(); - var arr = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Array, GetArrayIROpcodeByILCode(code), InstructionArgument.CreateVariable(arr), InstructionArgument.CreateVariable(index), InstructionArgument.CreateVariable(value)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Ceq: - case Code.Cgt: - case Code.Cgt_Un: - case Code.Clt: - case Code.Clt_Un: { - var op2 = _es.Pop(); - var op1 = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.Int32); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Compare, GetCompareIRCodeByILCode(code), InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(op1), InstructionArgument.CreateVariable(op2)); - AddInstruction(ir); - break; - } - case Code.Ldftn: { - var method = (IMethod)il.Operand; - var dst = _vs.CreateTempVar(_corLibTypes.IntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Ldftn, IROpCode.Ldftn, InstructionArgument.CreateVariable(dst)); - ir.inlineOperand = method; - AddInstruction(ir); - break; - } - case Code.Ldvirtftn: { - var method = (IMethod)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.IntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Ldftn, IROpCode.Ldvirtftn, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src) ); - ir.inlineOperand = method; - AddInstruction(ir); - break; - } - case Code.Localloc: { - var size = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.IntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Localloc, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(size)); - AddInstruction(ir); - break; - } - case Code.Unaligned: { - int alignment = (int)il.Operand; - prefixData = new PrefixData { code = PrefixCode.Unaligned, data = alignment }; - break; - } - case Code.Volatile: { - prefixData = new PrefixData { code = PrefixCode.Volatile }; - break; - } - case Code.Tailcall: { - prefixData = new PrefixData { code = PrefixCode.Tail }; - break; - } - case Code.Constrained: { - var klass = (ITypeDefOrRef)il.Operand; - prefixData = new PrefixData { code = PrefixCode.Constrained, data = klass }; - break; - } - case Code.Readonly: { - prefixData = new PrefixData { code = PrefixCode.ReadOnly }; - break; - } - case Code.No: { - prefixData = new PrefixData { code = PrefixCode.No, data = il.Operand }; - break; - } - case Code.Sizeof: { - var klass = (ITypeDefOrRef)il.Operand; - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Sizeof, InstructionArgument.CreateVariable(dst)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Mkrefany: { - var klass = (ITypeDefOrRef)il.Operand; - var value = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.TypedReference); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Ref, IROpCode.Mkrefany, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(value)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Refanytype: { - var src = _es.Pop(); - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Ref, IROpCode.Refanytype, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Refanyval: { - var klass = (ITypeDefOrRef)il.Operand; - var src = _es.Pop(); - var dst = _vs.CreateTempVar(klass.ToTypeSig()); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Ref, IROpCode.Refanyval, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src)); - ir.inlineOperand = klass; - AddInstruction(ir); - break; - } - case Code.Ldtoken: { - var token = (IMDTokenProvider)il.Operand; - var dst = _vs.CreateTempVar(_corLibTypes.UIntPtr); - _es.Push(dst); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Ldtoken, InstructionArgument.CreateVariable(dst)); - ir.inlineOperand = token; - AddInstruction(ir); - break; - } - case Code.Ckfinite: { - var src = _es.GetTop(); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Ckfinite, InstructionArgument.CreateVariable(src)); - AddInstruction(ir); - break; - } - case Code.Initblk: { - var size = _es.Pop(); - var value = _es.Pop(); - var src = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Initblk, InstructionArgument.CreateVariable(src), InstructionArgument.CreateVariable(value), InstructionArgument.CreateVariable(size)); - AddInstruction(ir); - break; - } - case Code.Cpblk: { - var size = _es.Pop(); - var src = _es.Pop(); - var dst = _es.Pop(); - var ir = IRInstruction.Create(IRFamily.Unspec, IROpCode.Cpblk, InstructionArgument.CreateVariable(dst), InstructionArgument.CreateVariable(src), InstructionArgument.CreateVariable(size)); - AddInstruction(ir); - break; - } - //case Code.Jmp: - default: throw new NotSupportedException($"method:{_methodDef} IL:{il}"); - } - } - - if (_curIrbb.nextIrbb != null) { - var flowControl = bb.Instructions.Last().OpCode.FlowControl; - if (flowControl != FlowControl.Return && flowControl != FlowControl.Branch && flowControl != FlowControl.Throw) { - _es.SaveInbound(_curIrbb.nextIrbb); - _curIrbb.AddOutboundBasicBlock(_curIrbb.nextIrbb); - } - } - _es.SaveOutbound(_curIrbb); - - } - - } -} diff --git a/Plugins/dnlib/IR/TypedConst.cs b/Plugins/dnlib/IR/TypedConst.cs deleted file mode 100644 index 280fe67..0000000 --- a/Plugins/dnlib/IR/TypedConst.cs +++ /dev/null @@ -1,49 +0,0 @@ -namespace dnlib.IR { - public class TypedConst { - public ConstType type; - public object value; - - - public static TypedConst CreateInt(int value) { - return new TypedConst { - type = ConstType.Int32, - value = value, - }; - } - - public static TypedConst CreateLong(long value) { - return new TypedConst { - type = ConstType.Int64, - value = value, - }; - } - - public static TypedConst CreateFloat(float value) { - return new TypedConst { - type = ConstType.Float, - value = value, - }; - } - - public static TypedConst CreateDouble(double value) { - return new TypedConst { - type = ConstType.Double, - value = value, - }; - } - - public static TypedConst CreateNull() { - return new TypedConst { - type = ConstType.Null, - value = null, - }; - } - - public static TypedConst CreateString(string value) { - return new TypedConst { - type = ConstType.String, - value = value, - }; - } - } -} diff --git a/Plugins/dnlib/IR/VariableInfo.cs b/Plugins/dnlib/IR/VariableInfo.cs deleted file mode 100644 index 98ba5f3..0000000 --- a/Plugins/dnlib/IR/VariableInfo.cs +++ /dev/null @@ -1,14 +0,0 @@ -using dnlib.DotNet; - - -namespace dnlib.IR { - public class VariableInfo { - public VariableLocation location; - public int id; - public int paramOrLocalIndex; - public string variableName; - public object paramOrLocalOrConst; - public TypeSig type; - public bool expandToInt; - } -} diff --git a/Plugins/dnlib/IR/VariableLocation.cs b/Plugins/dnlib/IR/VariableLocation.cs deleted file mode 100644 index 2698605..0000000 --- a/Plugins/dnlib/IR/VariableLocation.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace dnlib.IR { - //public abstract class InstructionArgumentData { - // public ArgumentDataType type; - //} - - public enum VariableLocation { - Argument, - Local, - Temp, - } -} diff --git a/Plugins/dnlib/IR/VariableSet.cs b/Plugins/dnlib/IR/VariableSet.cs deleted file mode 100644 index 744d20b..0000000 --- a/Plugins/dnlib/IR/VariableSet.cs +++ /dev/null @@ -1,168 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - - -namespace dnlib.IR { - public class VariableSet { - private readonly ModuleDef _module; - private readonly ICorLibTypes _corLibTypes; - - private readonly List _variables = new List(); - private int _nextId; - private readonly List _arguments = new List(); - private readonly List _locals = new List(); - - public VariableSet(ModuleDef module) { - _module = module; - _corLibTypes = module.CorLibTypes; - } - - int GetNextId() { - return _nextId++; - } - - public IList Variables => _variables; - - public IList Arguments => _arguments; - - public IList Locals => _locals; - - public void InitParams(IEnumerable ps) { - foreach (var p in ps) { - var v = new VariableInfo { - location = VariableLocation.Argument, - id = GetNextId(), - paramOrLocalIndex = p.Index, - variableName = p.Name, - paramOrLocalOrConst = p, - type = p.Type, - expandToInt = false, - }; - Debug.Assert(p.Index == _arguments.Count); - _arguments.Add(v); - Debug.Assert(v.id == _variables.Count); - _variables.Add(v); - } - } - - public void InitLocals(IEnumerable ls) { - foreach (var l in ls) { - var v = new VariableInfo { - location = VariableLocation.Local, - id = GetNextId(), - paramOrLocalIndex = l.Index, - variableName = l.Name, - paramOrLocalOrConst = l, - type = l.Type, - expandToInt = false, - }; - Debug.Assert(l.Index == _locals.Count); - _locals.Add(v); - Debug.Assert(v.id == _variables.Count); - _variables.Add(v); - } - } - - - - private bool TryConvertToExpandType(TypeSig type, out TypeSig expandType) { - type = type.RemovePinnedAndModifiers(); - expandType = type; - switch (type.ElementType) { - case ElementType.Boolean: - case ElementType.Char: - case ElementType.I1: - case ElementType.U1: - case ElementType.I2: - case ElementType.U2: expandType = type.Module.CorLibTypes.Int32; return true; - case ElementType.MVar: - case ElementType.Var: return false; - default: return true; - } - - } - - public VariableInfo CreateTempVar(TypeSig type, bool expandToInt = true) { - TypeSig expandType = type; - if (expandToInt) { - if (TryConvertToExpandType(type, out expandType)) { - expandToInt = false; - } - } - - var v = new VariableInfo { - location = VariableLocation.Temp, - id = GetNextId(), - paramOrLocalIndex = -1, - variableName = null, - paramOrLocalOrConst = null, - type = expandType, - expandToInt = expandToInt, - }; - Debug.Assert(v.id == _variables.Count); - _variables.Add(v); - return v; - } - - private TypeSig GetTypeSigByConstType(ConstType type) { - switch (type) { - case ConstType.Int32: return _corLibTypes.Int32; - case ConstType.Int64: return _corLibTypes.Int64; - case ConstType.Float: return _corLibTypes.Single; - case ConstType.Double: return _corLibTypes.Double; - case ConstType.String: return _corLibTypes.String; - case ConstType.Null: return _corLibTypes.UIntPtr; - case ConstType.RuntimeHandle: return _corLibTypes.UIntPtr; - default: throw new NotSupportedException(); - } - } - - public VariableInfo CreateConstVar(TypedConst value) { - var v = new VariableInfo { - location = VariableLocation.Temp, - id = GetNextId(), - paramOrLocalIndex = -1, - variableName = null, - paramOrLocalOrConst = null, - type = GetTypeSigByConstType(value.type), - expandToInt = false, - }; - Debug.Assert(v.id == _variables.Count); - _variables.Add(v); - return v; - } - - public VariableInfo GetParam(int index) { - return _arguments[index]; - } - - public VariableInfo GetLocal(int index) { - return _locals[index]; - } - - public VariableInfo GetVariable(int id) { - return _variables[id]; - } - - public VariableSet Rebuild(HashSet usedVars) { - var newVarSet = new VariableSet(_module); - - var newVars = newVarSet._variables; - newVars.AddRange(usedVars); - newVars.Sort((a, b) => a.id.CompareTo(b.id)); - - _nextId = newVars.Count; - - // rebuid id - for (int i = 0; i < newVars.Count; i++) { - newVars[i].id = i; - } - Console.WriteLine($"original varaible count:{_variables.Count} => trimed count:{newVars.Count}, reduce count:{_variables.Count - newVars.Count}"); - - return newVarSet; - } - } -} diff --git a/Plugins/dnlib/PE/Characteristics.cs b/Plugins/dnlib/PE/Characteristics.cs deleted file mode 100644 index 9ec6fe0..0000000 --- a/Plugins/dnlib/PE/Characteristics.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.PE { - /// - /// IMAGE_FILE_HEADER.Characteristics flags - /// - [Flags] - public enum Characteristics : ushort { - /// Relocation info stripped from file. - RelocsStripped = 0x0001, - /// File is executable (i.e. no unresolved externel references). - ExecutableImage = 0x0002, - /// Line nunbers stripped from file. - LineNumsStripped = 0x0004, - /// Local symbols stripped from file. - LocalSymsStripped = 0x0008, - /// Agressively trim working set - AggressiveWsTrim = 0x0010, - /// App can handle >2gb addresses - LargeAddressAware = 0x0020, - /// - Reserved1 = 0x0040, - /// Bytes of machine word are reversed. - BytesReversedLo = 0x0080, - /// 32 bit word machine. - Bit32Machine = 0x0100, - /// Debugging info stripped from file in .DBG file - DebugStripped = 0x0200, - /// If Image is on removable media, copy and run from the swap file. - RemovableRunFromSwap= 0x0400, - /// If Image is on Net, copy and run from the swap file. - NetRunFromSwap = 0x0800, - /// System File. - System = 0x1000, - /// File is a DLL. - Dll = 0x2000, - /// File should only be run on a UP machine - UpSystemOnly = 0x4000, - /// Bytes of machine word are reversed. - BytesReversedHi = 0x8000, - } -} diff --git a/Plugins/dnlib/PE/DllCharacteristics.cs b/Plugins/dnlib/PE/DllCharacteristics.cs deleted file mode 100644 index adc4745..0000000 --- a/Plugins/dnlib/PE/DllCharacteristics.cs +++ /dev/null @@ -1,44 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.PE { - /// - /// IMAGE_OPTIONAL_HEADER.DllCharacteristics - /// - [Flags] - public enum DllCharacteristics : ushort { - /// - Reserved1 = 0x0001, - /// - Reserved2 = 0x0002, - /// - Reserved3 = 0x0004, - /// - Reserved4 = 0x0008, - /// - Reserved5 = 0x0010, - /// Image can handle a high entropy 64-bit virtual address space. - HighEntropyVA = 0x0020, - /// DLL can move. - DynamicBase = 0x0040, - /// Code Integrity Image - ForceIntegrity = 0x0080, - /// Image is NX compatible - NxCompat = 0x0100, - /// Image understands isolation and doesn't want it - NoIsolation = 0x0200, - /// Image does not use SEH. No SE handler may reside in this image - NoSeh = 0x0400, - /// Do not bind this image. - NoBind = 0x0800, - /// Image should execute in an AppContainer - AppContainer = 0x1000, - /// Driver uses WDM model - WdmDriver = 0x2000, - /// Image supports Control Flow Guard. - GuardCf = 0x4000, - /// - TerminalServerAware = 0x8000, - } -} diff --git a/Plugins/dnlib/PE/IImageOptionalHeader.cs b/Plugins/dnlib/PE/IImageOptionalHeader.cs deleted file mode 100644 index 1fc97d2..0000000 --- a/Plugins/dnlib/PE/IImageOptionalHeader.cs +++ /dev/null @@ -1,165 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Interface for PE optional header classes - /// - public interface IImageOptionalHeader : IFileSection { - /// - /// Returns the Magic field - /// - ushort Magic { get; } - - /// - /// Returns the MajorLinkerVersion field - /// - byte MajorLinkerVersion { get; } - - /// - /// Returns the MinorLinkerVersion field - /// - byte MinorLinkerVersion { get; } - - /// - /// Returns the SizeOfCode field - /// - uint SizeOfCode { get; } - - /// - /// Returns the SizeOfInitializedData field - /// - uint SizeOfInitializedData { get; } - - /// - /// Returns the SizeOfUninitializedData field - /// - uint SizeOfUninitializedData { get; } - - /// - /// Returns the AddressOfEntryPoint field - /// - RVA AddressOfEntryPoint { get; } - - /// - /// Returns the BaseOfCode field - /// - RVA BaseOfCode { get; } - - /// - /// Returns the BaseOfData field - /// - RVA BaseOfData { get; } - - /// - /// Returns the ImageBase field - /// - ulong ImageBase { get; } - - /// - /// Returns the SectionAlignment field - /// - uint SectionAlignment { get; } - - /// - /// Returns the FileAlignment field - /// - uint FileAlignment { get; } - - /// - /// Returns the MajorOperatingSystemVersion field - /// - ushort MajorOperatingSystemVersion { get; } - - /// - /// Returns the MinorOperatingSystemVersion field - /// - ushort MinorOperatingSystemVersion { get; } - - /// - /// Returns the MajorImageVersion field - /// - ushort MajorImageVersion { get; } - - /// - /// Returns the MinorImageVersion field - /// - ushort MinorImageVersion { get; } - - /// - /// Returns the MajorSubsystemVersion field - /// - ushort MajorSubsystemVersion { get; } - - /// - /// Returns the MinorSubsystemVersion field - /// - ushort MinorSubsystemVersion { get; } - - /// - /// Returns the Win32VersionValue field - /// - uint Win32VersionValue { get; } - - /// - /// Returns the SizeOfImage field - /// - uint SizeOfImage { get; } - - /// - /// Returns the SizeOfHeaders field - /// - uint SizeOfHeaders { get; } - - /// - /// Returns the CheckSum field - /// - uint CheckSum { get; } - - /// - /// Returns the Subsystem field - /// - Subsystem Subsystem { get; } - - /// - /// Returns the DllCharacteristics field - /// - DllCharacteristics DllCharacteristics { get; } - - /// - /// Returns the SizeOfStackReserve field - /// - ulong SizeOfStackReserve { get; } - - /// - /// Returns the SizeOfStackCommit field - /// - ulong SizeOfStackCommit { get; } - - /// - /// Returns the SizeOfHeapReserve field - /// - ulong SizeOfHeapReserve { get; } - - /// - /// Returns the SizeOfHeapCommit field - /// - ulong SizeOfHeapCommit { get; } - - /// - /// Returns the LoaderFlags field - /// - uint LoaderFlags { get; } - - /// - /// Returns the NumberOfRvaAndSizes field - /// - uint NumberOfRvaAndSizes { get; } - - /// - /// Returns the DataDirectories field. This array contains exactly 16 elements. - /// - ImageDataDirectory[] DataDirectories { get; } - } -} diff --git a/Plugins/dnlib/PE/IPEImage.cs b/Plugins/dnlib/PE/IPEImage.cs deleted file mode 100644 index 744c255..0000000 --- a/Plugins/dnlib/PE/IPEImage.cs +++ /dev/null @@ -1,145 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.IO; -using dnlib.W32Resources; - -namespace dnlib.PE { - /// - /// Converts s to/from s - /// - public interface IRvaFileOffsetConverter { - /// - /// 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 , returns 0 if out of range - /// - /// The RVA to convert - /// The file offset - FileOffset ToFileOffset(RVA rva); - } - - /// - /// Interface to access a PE image - /// - public interface IPEImage : IRvaFileOffsetConverter, IDisposable { - /// - /// true if image layout is the same as the raw PE image layout, false - /// if it's the same layout as a PE image loaded by the OS PE loader. - /// - bool IsFileImageLayout { get; } - - /// - /// true if some of the memory where the image is located could be unavailable. - /// This could happen if it's been loaded by the OS loader. - /// - bool MayHaveInvalidAddresses { get; } - - /// - /// The filename or null if the data is not from a file - /// - string Filename { get; } - - /// - /// Returns the DOS header - /// - ImageDosHeader ImageDosHeader { get; } - - /// - /// Returns the NT headers - /// - ImageNTHeaders ImageNTHeaders { get; } - - /// - /// Returns the section headers - /// - IList ImageSectionHeaders { get; } - - /// - /// Returns the debug directories - /// - IList ImageDebugDirectories { get; } - - /// - /// Gets/sets the Win32 resources. This is null if there are no Win32 resources. - /// - Win32Resources Win32Resources { get; set; } - - /// - /// Gets the factory - /// - DataReaderFactory DataReaderFactory { get; } - - /// - /// Creates a from to the end of the image - /// - /// Offset of data - /// - DataReader CreateReader(FileOffset offset); - - /// - /// Creates a - /// - /// Offset of data - /// Length of data - /// - DataReader CreateReader(FileOffset offset, uint length); - - /// - /// Creates a from to the end of the image - /// - /// RVA of data - /// - DataReader CreateReader(RVA rva); - - /// - /// Creates a - /// - /// RVA of data - /// Length of data - /// - DataReader CreateReader(RVA rva, uint length); - - /// - /// Creates a that can read the whole image - /// - /// - DataReader CreateReader(); - } - - /// - /// Interface to access a PE image - /// - public interface IInternalPEImage : IPEImage { - /// - /// Call this to disable memory mapped I/O if it was used to open the file. This must only - /// be called if no other code is trying to access the memory since that could lead to an - /// exception. - /// - void UnsafeDisableMemoryMappedIO(); - - /// - /// true if memory mapped I/O is enabled - /// - bool IsMemoryMappedIO { get; } - } - - public static partial class PEExtensions { - /// - /// Finds a - /// - /// this - /// Type - /// Name - /// Language ID - /// The or null if none found - public static ResourceData FindWin32ResourceData(this IPEImage self, ResourceName type, ResourceName name, ResourceName langId) => - self.Win32Resources?.Find(type, name, langId); - } -} diff --git a/Plugins/dnlib/PE/IPEType.cs b/Plugins/dnlib/PE/IPEType.cs deleted file mode 100644 index 8846e40..0000000 --- a/Plugins/dnlib/PE/IPEType.cs +++ /dev/null @@ -1,26 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Converts a to/from an - /// - interface IPEType { - /// - /// Converts a to an , returns 0 if out of range - /// - /// The PEInfo context - /// The file offset to convert - /// The RVA - RVA ToRVA(PEInfo peInfo, FileOffset offset); - - /// - /// Converts an to a , returns 0 if out of range - /// - /// The PEInfo context - /// The RVA to convert - /// The file offset - FileOffset ToFileOffset(PEInfo peInfo, RVA rva); - } -} diff --git a/Plugins/dnlib/PE/ImageDataDirectory.cs b/Plugins/dnlib/PE/ImageDataDirectory.cs deleted file mode 100644 index 17a118e..0000000 --- a/Plugins/dnlib/PE/ImageDataDirectory.cs +++ /dev/null @@ -1,45 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_DATA_DIRECTORY PE section - /// - [DebuggerDisplay("{virtualAddress} {dataSize}")] - public sealed class ImageDataDirectory : FileSection { - readonly RVA virtualAddress; - readonly uint dataSize; - - /// - /// Returns the IMAGE_DATA_DIRECTORY.VirtualAddress field - /// - public RVA VirtualAddress => virtualAddress; - - /// - /// Returns the IMAGE_DATA_DIRECTORY.Size field - /// - public uint Size => dataSize; - - /// - /// Default constructor - /// - public ImageDataDirectory() { - } - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageDataDirectory(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - virtualAddress = (RVA)reader.ReadUInt32(); - dataSize = reader.ReadUInt32(); - SetEndoffset(ref reader); - } - } -} diff --git a/Plugins/dnlib/PE/ImageDebugDirectory.cs b/Plugins/dnlib/PE/ImageDebugDirectory.cs deleted file mode 100644 index 2769cfe..0000000 --- a/Plugins/dnlib/PE/ImageDebugDirectory.cs +++ /dev/null @@ -1,81 +0,0 @@ -// 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 => characteristics; - - /// - /// Gets the timestamp - /// - public uint TimeDateStamp => timeDateStamp; - - /// - /// Gets the major version - /// - public ushort MajorVersion => majorVersion; - - /// - /// Gets the minor version - /// - public ushort MinorVersion => minorVersion; - - /// - /// Gets the type - /// - public ImageDebugType Type => type; - - /// - /// Gets the size of data - /// - public uint SizeOfData => sizeOfData; - - /// - /// RVA of the data - /// - public RVA AddressOfRawData => (RVA)addressOfRawData; - - /// - /// File offset of the data - /// - public FileOffset PointerToRawData => (FileOffset)pointerToRawData; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageDebugDirectory(ref DataReader reader, bool verify) { - SetStartOffset(ref 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(ref reader); - } - } -} diff --git a/Plugins/dnlib/PE/ImageDebugType.cs b/Plugins/dnlib/PE/ImageDebugType.cs deleted file mode 100644 index bbb1306..0000000 --- a/Plugins/dnlib/PE/ImageDebugType.cs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 - /// - Reproducible = 16, - - /// - /// 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 - } -} diff --git a/Plugins/dnlib/PE/ImageDosHeader.cs b/Plugins/dnlib/PE/ImageDosHeader.cs deleted file mode 100644 index 79fa308..0000000 --- a/Plugins/dnlib/PE/ImageDosHeader.cs +++ /dev/null @@ -1,34 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_DOS_HEADER PE section - /// - public sealed class ImageDosHeader : FileSection { - readonly uint ntHeadersOffset; - - /// - /// File offset of the NT headers - /// - public uint NTHeadersOffset => ntHeadersOffset; - - /// - /// Constructor - /// - /// PE file reader - /// Verify section - /// Thrown if verification fails - public ImageDosHeader(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - ushort sig = reader.ReadUInt16(); - if (verify && sig != 0x5A4D) - throw new BadImageFormatException("Invalid DOS signature"); - reader.Position = (uint)startOffset + 0x3C; - ntHeadersOffset = reader.ReadUInt32(); - SetEndoffset(ref reader); - } - } -} diff --git a/Plugins/dnlib/PE/ImageFileHeader.cs b/Plugins/dnlib/PE/ImageFileHeader.cs deleted file mode 100644 index d4a9c71..0000000 --- a/Plugins/dnlib/PE/ImageFileHeader.cs +++ /dev/null @@ -1,74 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_FILE_HEADER PE section - /// - public sealed class ImageFileHeader : FileSection { - readonly Machine machine; - readonly ushort numberOfSections; - readonly uint timeDateStamp; - readonly uint pointerToSymbolTable; - readonly uint numberOfSymbols; - readonly ushort sizeOfOptionalHeader; - readonly Characteristics characteristics; - - /// - /// Returns the IMAGE_FILE_HEADER.Machine field - /// - public Machine Machine => machine; - - /// - /// Returns the IMAGE_FILE_HEADER.NumberOfSections field - /// - public int NumberOfSections => numberOfSections; - - /// - /// Returns the IMAGE_FILE_HEADER.TimeDateStamp field - /// - public uint TimeDateStamp => timeDateStamp; - - /// - /// Returns the IMAGE_FILE_HEADER.PointerToSymbolTable field - /// - public uint PointerToSymbolTable => pointerToSymbolTable; - - /// - /// Returns the IMAGE_FILE_HEADER.NumberOfSymbols field - /// - public uint NumberOfSymbols => numberOfSymbols; - - /// - /// Returns the IMAGE_FILE_HEADER.SizeOfOptionalHeader field - /// - public uint SizeOfOptionalHeader => sizeOfOptionalHeader; - - /// - /// Returns the IMAGE_FILE_HEADER.Characteristics field - /// - public Characteristics Characteristics => characteristics; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageFileHeader(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - machine = (Machine)reader.ReadUInt16(); - numberOfSections = reader.ReadUInt16(); - timeDateStamp = reader.ReadUInt32(); - pointerToSymbolTable = reader.ReadUInt32(); - numberOfSymbols = reader.ReadUInt32(); - sizeOfOptionalHeader = reader.ReadUInt16(); - characteristics = (Characteristics)reader.ReadUInt16(); - SetEndoffset(ref reader); - if (verify && sizeOfOptionalHeader == 0) - throw new BadImageFormatException("Invalid SizeOfOptionalHeader"); - } - } -} diff --git a/Plugins/dnlib/PE/ImageNTHeaders.cs b/Plugins/dnlib/PE/ImageNTHeaders.cs deleted file mode 100644 index 87404e5..0000000 --- a/Plugins/dnlib/PE/ImageNTHeaders.cs +++ /dev/null @@ -1,64 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_NT_HEADERS PE section - /// - public sealed class ImageNTHeaders : FileSection { - readonly uint signature; - readonly ImageFileHeader imageFileHeader; - readonly IImageOptionalHeader imageOptionalHeader; - - /// - /// Returns the IMAGE_NT_HEADERS.Signature field - /// - public uint Signature => signature; - - /// - /// Returns the IMAGE_NT_HEADERS.FileHeader field - /// - public ImageFileHeader FileHeader => imageFileHeader; - - /// - /// Returns the IMAGE_NT_HEADERS.OptionalHeader field - /// - public IImageOptionalHeader OptionalHeader => imageOptionalHeader; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageNTHeaders(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - signature = reader.ReadUInt32(); - // 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); - SetEndoffset(ref reader); - } - - /// - /// Creates an IImageOptionalHeader - /// - /// PE file reader pointing to the start of the optional header - /// Verify section - /// The created IImageOptionalHeader - /// Thrown if verification fails - IImageOptionalHeader CreateImageOptionalHeader(ref DataReader reader, bool verify) { - ushort magic = reader.ReadUInt16(); - reader.Position -= 2; - 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/Plugins/dnlib/PE/ImageOptionalHeader32.cs b/Plugins/dnlib/PE/ImageOptionalHeader32.cs deleted file mode 100644 index d03172d..0000000 --- a/Plugins/dnlib/PE/ImageOptionalHeader32.cs +++ /dev/null @@ -1,252 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_OPTIONAL_HEADER (32-bit) PE section - /// - public sealed class ImageOptionalHeader32 : FileSection, IImageOptionalHeader { - readonly ushort magic; - readonly byte majorLinkerVersion; - readonly byte minorLinkerVersion; - readonly uint sizeOfCode; - readonly uint sizeOfInitializedData; - readonly uint sizeOfUninitializedData; - readonly RVA addressOfEntryPoint; - readonly RVA baseOfCode; - readonly RVA baseOfData; - readonly uint imageBase; - readonly uint sectionAlignment; - readonly uint fileAlignment; - readonly ushort majorOperatingSystemVersion; - readonly ushort minorOperatingSystemVersion; - readonly ushort majorImageVersion; - readonly ushort minorImageVersion; - readonly ushort majorSubsystemVersion; - readonly ushort minorSubsystemVersion; - readonly uint win32VersionValue; - readonly uint sizeOfImage; - readonly uint sizeOfHeaders; - readonly uint checkSum; - readonly Subsystem subsystem; - readonly DllCharacteristics dllCharacteristics; - readonly uint sizeOfStackReserve; - readonly uint sizeOfStackCommit; - readonly uint sizeOfHeapReserve; - readonly uint sizeOfHeapCommit; - readonly uint loaderFlags; - readonly uint numberOfRvaAndSizes; - readonly ImageDataDirectory[] dataDirectories = new ImageDataDirectory[16]; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.Magic field - /// - public ushort Magic => magic; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MajorLinkerVersion field - /// - public byte MajorLinkerVersion => majorLinkerVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MinorLinkerVersion field - /// - public byte MinorLinkerVersion => minorLinkerVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfCode field - /// - public uint SizeOfCode => sizeOfCode; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfInitializedData field - /// - public uint SizeOfInitializedData => sizeOfInitializedData; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfUninitializedData field - /// - public uint SizeOfUninitializedData => sizeOfUninitializedData; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.AddressOfEntryPoint field - /// - public RVA AddressOfEntryPoint => addressOfEntryPoint; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.BaseOfCode field - /// - public RVA BaseOfCode => baseOfCode; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.BaseOfData field - /// - public RVA BaseOfData => baseOfData; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.ImageBase field - /// - public ulong ImageBase => imageBase; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SectionAlignment field - /// - public uint SectionAlignment => sectionAlignment; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.FileAlignment field - /// - public uint FileAlignment => fileAlignment; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MajorOperatingSystemVersion field - /// - public ushort MajorOperatingSystemVersion => majorOperatingSystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MinorOperatingSystemVersion field - /// - public ushort MinorOperatingSystemVersion => minorOperatingSystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MajorImageVersion field - /// - public ushort MajorImageVersion => majorImageVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MinorImageVersion field - /// - public ushort MinorImageVersion => minorImageVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MajorSubsystemVersion field - /// - public ushort MajorSubsystemVersion => majorSubsystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.MinorSubsystemVersion field - /// - public ushort MinorSubsystemVersion => minorSubsystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.Win32VersionValue field - /// - public uint Win32VersionValue => win32VersionValue; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfImage field - /// - public uint SizeOfImage => sizeOfImage; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeaders field - /// - public uint SizeOfHeaders => sizeOfHeaders; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.CheckSum field - /// - public uint CheckSum => checkSum; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.Subsystem field - /// - public Subsystem Subsystem => subsystem; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.DllCharacteristics field - /// - public DllCharacteristics DllCharacteristics => dllCharacteristics; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackReserve field - /// - public ulong SizeOfStackReserve => sizeOfStackReserve; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfStackCommit field - /// - public ulong SizeOfStackCommit => sizeOfStackCommit; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapReserve field - /// - public ulong SizeOfHeapReserve => sizeOfHeapReserve; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.SizeOfHeapCommit field - /// - public ulong SizeOfHeapCommit => sizeOfHeapCommit; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.LoaderFlags field - /// - public uint LoaderFlags => loaderFlags; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.NumberOfRvaAndSizes field - /// - public uint NumberOfRvaAndSizes => numberOfRvaAndSizes; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER.DataDirectories field - /// - public ImageDataDirectory[] DataDirectories => dataDirectories; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Total size of this optional header (from the file header) - /// Verify section - /// Thrown if verification fails - public ImageOptionalHeader32(ref DataReader reader, uint totalSize, bool verify) { - if (totalSize < 0x60) - throw new BadImageFormatException("Invalid optional header size"); - if (verify && (ulong)reader.Position + totalSize > reader.Length) - throw new BadImageFormatException("Invalid optional header size"); - SetStartOffset(ref reader); - 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 = reader.Position - (uint)startOffset; - if (len + 8 <= totalSize) - dataDirectories[i] = new ImageDataDirectory(ref reader, verify); - else - dataDirectories[i] = new ImageDataDirectory(); - } - reader.Position = (uint)startOffset + totalSize; - SetEndoffset(ref reader); - } - } -} diff --git a/Plugins/dnlib/PE/ImageOptionalHeader64.cs b/Plugins/dnlib/PE/ImageOptionalHeader64.cs deleted file mode 100644 index a0a1efb..0000000 --- a/Plugins/dnlib/PE/ImageOptionalHeader64.cs +++ /dev/null @@ -1,250 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_OPTIONAL_HEADER64 PE section - /// - public sealed class ImageOptionalHeader64 : FileSection, IImageOptionalHeader { - readonly ushort magic; - readonly byte majorLinkerVersion; - readonly byte minorLinkerVersion; - readonly uint sizeOfCode; - readonly uint sizeOfInitializedData; - readonly uint sizeOfUninitializedData; - readonly RVA addressOfEntryPoint; - readonly RVA baseOfCode; - readonly ulong imageBase; - readonly uint sectionAlignment; - readonly uint fileAlignment; - readonly ushort majorOperatingSystemVersion; - readonly ushort minorOperatingSystemVersion; - readonly ushort majorImageVersion; - readonly ushort minorImageVersion; - readonly ushort majorSubsystemVersion; - readonly ushort minorSubsystemVersion; - readonly uint win32VersionValue; - readonly uint sizeOfImage; - readonly uint sizeOfHeaders; - readonly uint checkSum; - readonly Subsystem subsystem; - readonly DllCharacteristics dllCharacteristics; - readonly ulong sizeOfStackReserve; - readonly ulong sizeOfStackCommit; - readonly ulong sizeOfHeapReserve; - readonly ulong sizeOfHeapCommit; - readonly uint loaderFlags; - readonly uint numberOfRvaAndSizes; - readonly ImageDataDirectory[] dataDirectories = new ImageDataDirectory[16]; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.Magic field - /// - public ushort Magic => magic; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MajorLinkerVersion field - /// - public byte MajorLinkerVersion => majorLinkerVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MinorLinkerVersion field - /// - public byte MinorLinkerVersion => minorLinkerVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfCode field - /// - public uint SizeOfCode => sizeOfCode; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfInitializedData field - /// - public uint SizeOfInitializedData => sizeOfInitializedData; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfUninitializedData field - /// - public uint SizeOfUninitializedData => sizeOfUninitializedData; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.AddressOfEntryPoint field - /// - public RVA AddressOfEntryPoint => addressOfEntryPoint; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.BaseOfCode field - /// - public RVA BaseOfCode => baseOfCode; - - /// - /// Returns 0 since BaseOfData is not present in IMAGE_OPTIONAL_HEADER64 - /// - public RVA BaseOfData => 0; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.ImageBase field - /// - public ulong ImageBase => imageBase; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SectionAlignment field - /// - public uint SectionAlignment => sectionAlignment; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.FileAlignment field - /// - public uint FileAlignment => fileAlignment; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MajorOperatingSystemVersion field - /// - public ushort MajorOperatingSystemVersion => majorOperatingSystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MinorOperatingSystemVersion field - /// - public ushort MinorOperatingSystemVersion => minorOperatingSystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MajorImageVersion field - /// - public ushort MajorImageVersion => majorImageVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MinorImageVersion field - /// - public ushort MinorImageVersion => minorImageVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MajorSubsystemVersion field - /// - public ushort MajorSubsystemVersion => majorSubsystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.MinorSubsystemVersion field - /// - public ushort MinorSubsystemVersion => minorSubsystemVersion; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.Win32VersionValue field - /// - public uint Win32VersionValue => win32VersionValue; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfImage field - /// - public uint SizeOfImage => sizeOfImage; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeaders field - /// - public uint SizeOfHeaders => sizeOfHeaders; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.CheckSum field - /// - public uint CheckSum => checkSum; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.Subsystem field - /// - public Subsystem Subsystem => subsystem; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.DllCharacteristics field - /// - public DllCharacteristics DllCharacteristics => dllCharacteristics; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfStackReserve field - /// - public ulong SizeOfStackReserve => sizeOfStackReserve; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfStackCommit field - /// - public ulong SizeOfStackCommit => sizeOfStackCommit; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeapReserve field - /// - public ulong SizeOfHeapReserve => sizeOfHeapReserve; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.SizeOfHeapCommit field - /// - public ulong SizeOfHeapCommit => sizeOfHeapCommit; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.LoaderFlags field - /// - public uint LoaderFlags => loaderFlags; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.NumberOfRvaAndSizes field - /// - public uint NumberOfRvaAndSizes => numberOfRvaAndSizes; - - /// - /// Returns the IMAGE_OPTIONAL_HEADER64.DataDirectories field - /// - public ImageDataDirectory[] DataDirectories => dataDirectories; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Total size of this optional header (from the file header) - /// Verify section - /// Thrown if verification fails - public ImageOptionalHeader64(ref DataReader reader, uint totalSize, bool verify) { - if (totalSize < 0x70) - throw new BadImageFormatException("Invalid optional header size"); - if (verify && (ulong)reader.Position + totalSize > reader.Length) - throw new BadImageFormatException("Invalid optional header size"); - SetStartOffset(ref reader); - 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 = reader.Position - (uint)startOffset; - if (len + 8 <= totalSize) - dataDirectories[i] = new ImageDataDirectory(ref reader, verify); - else - dataDirectories[i] = new ImageDataDirectory(); - } - reader.Position = (uint)startOffset + totalSize; - SetEndoffset(ref reader); - } - } -} diff --git a/Plugins/dnlib/PE/ImageSectionHeader.cs b/Plugins/dnlib/PE/ImageSectionHeader.cs deleted file mode 100644 index 326028c..0000000 --- a/Plugins/dnlib/PE/ImageSectionHeader.cs +++ /dev/null @@ -1,114 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Text; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// Represents the IMAGE_SECTION_HEADER PE section - /// - [DebuggerDisplay("RVA:{virtualAddress} VS:{virtualSize} FO:{pointerToRawData} FS:{sizeOfRawData} {displayName}")] - public sealed class ImageSectionHeader : FileSection { - readonly string displayName; - readonly byte[] name; - readonly uint virtualSize; - readonly RVA virtualAddress; - readonly uint sizeOfRawData; - readonly uint pointerToRawData; - readonly uint pointerToRelocations; - readonly uint pointerToLinenumbers; - readonly ushort numberOfRelocations; - readonly ushort numberOfLinenumbers; - readonly uint characteristics; - - /// - /// Returns the human readable section name, ignoring everything after - /// the first nul byte - /// - public string DisplayName => displayName; - - /// - /// Returns the IMAGE_SECTION_HEADER.Name field - /// - public byte[] Name => name; - - /// - /// Returns the IMAGE_SECTION_HEADER.VirtualSize field - /// - public uint VirtualSize => virtualSize; - - /// - /// Returns the IMAGE_SECTION_HEADER.VirtualAddress field - /// - public RVA VirtualAddress => virtualAddress; - - /// - /// Returns the IMAGE_SECTION_HEADER.SizeOfRawData field - /// - public uint SizeOfRawData => sizeOfRawData; - - /// - /// Returns the IMAGE_SECTION_HEADER.PointerToRawData field - /// - public uint PointerToRawData => pointerToRawData; - - /// - /// Returns the IMAGE_SECTION_HEADER.PointerToRelocations field - /// - public uint PointerToRelocations => pointerToRelocations; - - /// - /// Returns the IMAGE_SECTION_HEADER.PointerToLinenumbers field - /// - public uint PointerToLinenumbers => pointerToLinenumbers; - - /// - /// Returns the IMAGE_SECTION_HEADER.NumberOfRelocations field - /// - public ushort NumberOfRelocations => numberOfRelocations; - - /// - /// Returns the IMAGE_SECTION_HEADER.NumberOfLinenumbers field - /// - public ushort NumberOfLinenumbers => numberOfLinenumbers; - - /// - /// Returns the IMAGE_SECTION_HEADER.Characteristics field - /// - public uint Characteristics => characteristics; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify section - /// Thrown if verification fails - public ImageSectionHeader(ref DataReader reader, bool verify) { - SetStartOffset(ref reader); - 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(ref reader); - displayName = ToString(name); - } - - static string ToString(byte[] name) { - var sb = new StringBuilder(name.Length); - foreach (var b in name) { - if (b == 0) - break; - sb.Append((char)b); - } - return sb.ToString(); - } - } -} diff --git a/Plugins/dnlib/PE/Machine.cs b/Plugins/dnlib/PE/Machine.cs deleted file mode 100644 index 7cacdd0..0000000 --- a/Plugins/dnlib/PE/Machine.cs +++ /dev/null @@ -1,244 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.PE { - /// - /// IMAGE_FILE_HEADER.Machine enum - /// - public enum Machine : ushort { - /// Unknown machine - Unknown = 0, - /// x86 - I386 = 0x014C, - /// MIPS little-endian, 0x160 big-endian - R3000 = 0x0162, - /// MIPS little-endian - R4000 = 0x0166, - /// MIPS little-endian - R10000 = 0x0168, - /// MIPS little-endian WCE v2 - WCEMIPSV2 = 0x0169, - /// Alpha_AXP - ALPHA = 0x0184, - /// SH3 little-endian - SH3 = 0x01A2, - /// - SH3DSP = 0x01A3, - /// SH3E little-endian - SH3E = 0x01A4, - /// SH4 little-endian - SH4 = 0x01A6, - /// SH5 - SH5 = 0x01A8, - /// ARM Little-Endian - ARM = 0x01C0, - /// ARM Thumb/Thumb-2 Little-Endian - THUMB = 0x01C2, - /// ARM Thumb-2 Little-Endian - ARMNT = 0x01C4, - /// - AM33 = 0x01D3, - /// IBM PowerPC Little-Endian - POWERPC = 0x01F0, - /// - POWERPCFP = 0x01F1, - /// IA-64 - IA64 = 0x0200, - /// - MIPS16 = 0x0266, - /// - ALPHA64 = 0x0284, - /// - MIPSFPU = 0x0366, - /// - MIPSFPU16 = 0x0466, - /// Infineon - TRICORE = 0x0520, - /// - CEF = 0x0CEF, - /// EFI Byte Code - EBC = 0x0EBC, - /// x64 - AMD64 = 0x8664, - /// M32R little-endian - M32R = 0x9041, - /// - 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, - 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 - } - - /// - /// Extensions - /// - public static class MachineExtensions { - /// - /// Checks if is a 64-bit machine - /// - /// Machine - /// - 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.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; - - // 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; - } - } - - /// - /// 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: - case Machine.I386_Native_Sun: - 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: - case Machine.AMD64_Native_Sun: - 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: - case Machine.ARMNT_Native_Sun: - 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: - case Machine.ARM64_Native_Sun: - return true; - default: - 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; - } - } - } -} diff --git a/Plugins/dnlib/PE/PEExtensions.cs b/Plugins/dnlib/PE/PEExtensions.cs deleted file mode 100644 index eeef50d..0000000 --- a/Plugins/dnlib/PE/PEExtensions.cs +++ /dev/null @@ -1,50 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.IO; - -namespace dnlib.PE { - /// - /// Extension methods - /// - public static partial class PEExtensions { - /// - /// Calculates a PE checksum - /// - /// PE image stream positioned at the MZ bytes - /// Length of image - /// Offset of checksum - /// PE checksum - 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; - checkSum = CalculatePECheckSum(stream, checkSumOffset, 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); - } - - 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); - } -} diff --git a/Plugins/dnlib/PE/PEImage.cs b/Plugins/dnlib/PE/PEImage.cs deleted file mode 100644 index 023f7ac..0000000 --- a/Plugins/dnlib/PE/PEImage.cs +++ /dev/null @@ -1,371 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.IO; -using dnlib.IO; -using dnlib.Utils; -using dnlib.W32Resources; -using dnlib.Threading; - -namespace dnlib.PE { - /// - /// Image layout - /// - public enum ImageLayout { - /// - /// Use this if the PE file has a normal structure (eg. it's been read from a file on disk) - /// - File, - - /// - /// Use this if the PE file has been loaded into memory by the OS PE file loader - /// - Memory, - } - - /// - /// Accesses a PE file - /// - public sealed class PEImage : IInternalPEImage { - // Default to false because an OS loaded PE image may contain memory holes. If there - // are memory holes, other code (eg. .NET resource creator) must verify that all memory - // is available, which will be slower. - const bool USE_MEMORY_LAYOUT_WITH_MAPPED_FILES = false; - - static readonly IPEType MemoryLayout = new MemoryPEType(); - static readonly IPEType FileLayout = new FilePEType(); - - DataReaderFactory dataReaderFactory; - IPEType peType; - PEInfo peInfo; - UserValue win32Resources; -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - sealed class FilePEType : IPEType { - public RVA ToRVA(PEInfo peInfo, FileOffset offset) => peInfo.ToRVA(offset); - public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) => peInfo.ToFileOffset(rva); - } - - sealed class MemoryPEType : IPEType { - public RVA ToRVA(PEInfo peInfo, FileOffset offset) => (RVA)offset; - public FileOffset ToFileOffset(PEInfo peInfo, RVA rva) => (FileOffset)rva; - } - - /// - public bool IsFileImageLayout => peType is FilePEType; - - /// - public bool MayHaveInvalidAddresses => !IsFileImageLayout; - - /// - public string Filename => dataReaderFactory.Filename; - - /// - public ImageDosHeader ImageDosHeader => peInfo.ImageDosHeader; - - /// - public ImageNTHeaders ImageNTHeaders => peInfo.ImageNTHeaders; - - /// - public IList ImageSectionHeaders => peInfo.ImageSectionHeaders; - - /// - public IList ImageDebugDirectories { - get { - if (imageDebugDirectories is null) - imageDebugDirectories = ReadImageDebugDirectories(); - return imageDebugDirectories; - } - } - ImageDebugDirectory[] imageDebugDirectories; - - /// - public DataReaderFactory DataReaderFactory => dataReaderFactory; - - /// - public Win32Resources Win32Resources { - get => win32Resources.Value; - set { - IDisposable origValue = null; - if (win32Resources.IsValueInitialized) { - origValue = win32Resources.Value; - if (origValue == value) - return; - } - win32Resources.Value = value; - - if (origValue is not null) - origValue.Dispose(); - } - } - - /// - /// Constructor - /// - /// Data reader factory - /// Image layout - /// Verify PE file data - public PEImage(DataReaderFactory dataReaderFactory, ImageLayout imageLayout, bool verify) { - try { - this.dataReaderFactory = dataReaderFactory; - peType = ConvertImageLayout(imageLayout); - var reader = dataReaderFactory.CreateReader(); - peInfo = new PEInfo(ref reader, verify); - Initialize(); - } - catch { - Dispose(); - throw; - } - } - - void Initialize() { - win32Resources.ReadOriginalValue = () => { - var dataDir = peInfo.ImageNTHeaders.OptionalHeader.DataDirectories[2]; - if (dataDir.VirtualAddress == 0 || dataDir.Size == 0) - return null; - return new Win32ResourcesPE(this); - }; -#if THREAD_SAFE - win32Resources.Lock = theLock; -#endif - } - - static IPEType ConvertImageLayout(ImageLayout imageLayout) => - imageLayout switch { - ImageLayout.File => FileLayout, - ImageLayout.Memory => MemoryLayout, - _ => throw new ArgumentException("imageLayout"), - }; - - /// - /// Constructor - /// - /// Name of the file - /// true if we should map it as an executable - /// Verify PE file data - internal PEImage(string filename, bool mapAsImage, bool verify) - : this(DataReaderFactoryFactory.Create(filename, mapAsImage), mapAsImage ? ImageLayout.Memory : ImageLayout.File, verify) { - try { - if (mapAsImage && dataReaderFactory is MemoryMappedDataReaderFactory) - ((MemoryMappedDataReaderFactory)dataReaderFactory).SetLength(peInfo.GetImageSize()); - } - catch { - Dispose(); - throw; - } - } - - /// - /// Constructor - /// - /// Name of the file - /// Verify PE file data - public PEImage(string filename, bool verify) - : this(filename, USE_MEMORY_LAYOUT_WITH_MAPPED_FILES, verify) { - } - - /// - /// Constructor - /// - /// Name of the file - 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(ByteArrayDataReaderFactory.Create(data, filename), imageLayout, verify) { - } - - /// - /// Constructor - /// - /// The PE file data - /// Image layout - /// Verify PE file data - public PEImage(byte[] data, ImageLayout imageLayout, bool verify) - : this(data, null, imageLayout, verify) { - } - - /// - /// Constructor - /// - /// The PE file data - /// Verify PE file data - public PEImage(byte[] data, bool 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) { - } - - /// - /// Constructor - /// - /// The PE file data - public PEImage(byte[] data) - : this(data, null, true) { - } - - /// - /// Constructor - /// - /// The PE file data - /// Filename or null - public PEImage(byte[] data, string filename) - : this(data, filename, true) { - } - - /// - /// Constructor - /// - /// Address of PE image - /// Length of PE image - /// Image layout - /// Verify PE file data - public unsafe PEImage(IntPtr baseAddr, uint length, ImageLayout imageLayout, bool verify) - : this(NativeMemoryDataReaderFactory.Create((byte*)baseAddr, length, filename: null), imageLayout, verify) { - } - - /// - /// Constructor - /// - /// Address of PE image - /// Length of PE image - /// Verify PE file data - public PEImage(IntPtr baseAddr, uint length, bool verify) - : this(baseAddr, length, ImageLayout.Memory, verify) { - } - - /// - /// Constructor - /// - /// Address of PE image - /// Length of PE image - public PEImage(IntPtr baseAddr, uint length) - : this(baseAddr, length, true) { - } - - /// - /// Constructor - /// - /// Address of PE image - /// Image layout - /// Verify PE file data - public unsafe PEImage(IntPtr baseAddr, ImageLayout imageLayout, bool verify) - : this(NativeMemoryDataReaderFactory.Create((byte*)baseAddr, 0x10000, filename: null), imageLayout, verify) { - try { - ((NativeMemoryDataReaderFactory)dataReaderFactory).SetLength(peInfo.GetImageSize()); - } - catch { - Dispose(); - throw; - } - } - - /// - /// Constructor - /// - /// Address of PE image - /// Verify PE file data - public PEImage(IntPtr baseAddr, bool verify) - : this(baseAddr, ImageLayout.Memory, verify) { - } - - /// - /// Constructor - /// - /// Address of PE image - public PEImage(IntPtr baseAddr) - : this(baseAddr, true) { - } - - /// - public RVA ToRVA(FileOffset offset) => peType.ToRVA(peInfo, offset); - - /// - public FileOffset ToFileOffset(RVA rva) => peType.ToFileOffset(peInfo, rva); - - /// - public void Dispose() { - IDisposable id; - if (win32Resources.IsValueInitialized && (id = win32Resources.Value) is not null) - id.Dispose(); - dataReaderFactory?.Dispose(); - win32Resources.Value = null; - dataReaderFactory = null; - peType = null; - peInfo = null; - } - - /// - public DataReader CreateReader(FileOffset offset) => - DataReaderFactory.CreateReader((uint)offset, DataReaderFactory.Length - (uint)offset); - - /// - public DataReader CreateReader(FileOffset offset, uint length) => - DataReaderFactory.CreateReader((uint)offset, length); - - /// - public DataReader CreateReader(RVA rva) => CreateReader(ToFileOffset(rva)); - - /// - public DataReader CreateReader(RVA rva, uint length) => CreateReader(ToFileOffset(rva), length); - - /// - public DataReader CreateReader() => DataReaderFactory.CreateReader(); - - void IInternalPEImage.UnsafeDisableMemoryMappedIO() { - if (dataReaderFactory is MemoryMappedDataReaderFactory creator) - creator.UnsafeDisableMemoryMappedIO(); - } - - bool IInternalPEImage.IsMemoryMappedIO { - get { - var creator = dataReaderFactory as MemoryMappedDataReaderFactory; - return creator is null ? false : creator.IsMemoryMappedIO; - } - } - - ImageDebugDirectory[] ReadImageDebugDirectories() { - try { - var dataDir = ImageNTHeaders.OptionalHeader.DataDirectories[6]; - if (dataDir.VirtualAddress == 0) - return Array2.Empty(); - var reader = DataReaderFactory.CreateReader(); - if (dataDir.Size > reader.Length) - return Array2.Empty(); - int count = (int)(dataDir.Size / 0x1C); - if (count == 0) - return Array2.Empty(); - reader.CurrentOffset = (uint)ToFileOffset(dataDir.VirtualAddress); - if ((ulong)reader.CurrentOffset + dataDir.Size > reader.Length) - return Array2.Empty(); - var res = new ImageDebugDirectory[count]; - for (int i = 0; i < res.Length; i++) - res[i] = new ImageDebugDirectory(ref reader, true); - return res; - } - catch (IOException) { - } - return Array2.Empty(); - } - } -} diff --git a/Plugins/dnlib/PE/PEInfo.cs b/Plugins/dnlib/PE/PEInfo.cs deleted file mode 100644 index 3065c25..0000000 --- a/Plugins/dnlib/PE/PEInfo.cs +++ /dev/null @@ -1,153 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.PE { - /// - /// 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; - readonly ImageNTHeaders imageNTHeaders; - readonly ImageSectionHeader[] imageSectionHeaders; - - /// - /// Returns the DOS header - /// - public ImageDosHeader ImageDosHeader => imageDosHeader; - - /// - /// Returns the NT headers - /// - public ImageNTHeaders ImageNTHeaders => imageNTHeaders; - - /// - /// Returns the section headers - /// - public ImageSectionHeader[] ImageSectionHeaders => imageSectionHeaders; - - /// - /// Constructor - /// - /// PE file reader pointing to the start of this section - /// Verify sections - /// Thrown if verification fails - public PEInfo(ref DataReader reader, bool verify) { - reader.Position = 0; - imageDosHeader = new ImageDosHeader(ref reader, verify); - - if (verify && imageDosHeader.NTHeadersOffset == 0) - throw new BadImageFormatException("Invalid NT headers offset"); - reader.Position = imageDosHeader.NTHeadersOffset; - imageNTHeaders = new ImageNTHeaders(ref reader, verify); - - reader.Position = (uint)imageNTHeaders.OptionalHeader.StartOffset + imageNTHeaders.FileHeader.SizeOfOptionalHeader; - 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); - } - - /// - /// Returns the first that has data at file offset - /// - /// - /// The file offset - /// - public ImageSectionHeader ToImageSectionHeader(FileOffset offset) { - foreach (var section in imageSectionHeaders) { - if ((uint)offset >= section.PointerToRawData && (uint)offset < section.PointerToRawData + section.SizeOfRawData) - return section; - } - return null; - } - - /// - /// Returns the first that has data at RVA - /// - /// - /// The RVA - /// - public ImageSectionHeader ToImageSectionHeader(RVA rva) { - uint alignment = imageNTHeaders.OptionalHeader.SectionAlignment; - foreach (var section in imageSectionHeaders) { - if (rva >= section.VirtualAddress && rva < section.VirtualAddress + DotNet.Utils.AlignUp(section.VirtualSize, alignment)) - return section; - } - return null; - } - - /// - /// 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 , 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) { - 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; - } - - static ulong AlignUp(ulong val, uint alignment) => (val + alignment - 1) & ~(ulong)(alignment - 1); - - /// - /// Returns size of image rounded up to - /// - /// It calculates the size itself, and does not return - /// Size of image in bytes - public uint GetImageSize() { - var optHdr = ImageNTHeaders.OptionalHeader; - uint alignment = optHdr.SectionAlignment; - 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); - } - } -} diff --git a/Plugins/dnlib/PE/ProcessorArchUtils.cs b/Plugins/dnlib/PE/ProcessorArchUtils.cs deleted file mode 100644 index 57599e1..0000000 --- a/Plugins/dnlib/PE/ProcessorArchUtils.cs +++ /dev/null @@ -1,157 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Reflection; -using System.Runtime.InteropServices; - -namespace dnlib.PE { - static class ProcessorArchUtils { - static Machine cachedMachine = 0; - - public static Machine GetProcessCpuArchitecture() { - if (cachedMachine == 0) - cachedMachine = GetProcessCpuArchitectureCore(); - return cachedMachine; - } - - static class RuntimeInformationUtils { -#if NETSTANDARD || NETCOREAPP - public static bool TryGet_RuntimeInformation_Architecture(out Machine machine) => - TryGetArchitecture((int)RuntimeInformation.ProcessArchitecture, out machine); -#else - 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) { - machine = 0; - var processArchitectureMethod = System_Runtime_InteropServices_RuntimeInformation?.GetMethod("get_ProcessArchitecture", Array2.Empty()); - if (processArchitectureMethod is null) - return false; - - var result = processArchitectureMethod.Invoke(null, Array2.Empty()); - 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; - 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: - Debug.Fail($"Unknown process architecture: {architecture}"); - machine = 0; - return false; - } - } - } - - static Machine GetProcessCpuArchitectureCore() { - 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 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; - } - - enum ProcessorArchitecture : ushort { - INTEL = 0, - ARM = 5, - IA64 = 6, - AMD64 = 9, - ARM64 = 12, - UNKNOWN = 0xFFFF, - } - - 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; - } - } - catch (EntryPointNotFoundException) { - canTryGetSystemInfo = false; - } - catch (DllNotFoundException) { - canTryGetSystemInfo = false; - } - } - - machine = 0; - return false; - } - static bool canTryGetSystemInfo = true; - } - } -} diff --git a/Plugins/dnlib/PE/RVA.cs b/Plugins/dnlib/PE/RVA.cs deleted file mode 100644 index 14cc70f..0000000 --- a/Plugins/dnlib/PE/RVA.cs +++ /dev/null @@ -1,25 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.PE { - /// - /// Represents an RVA (relative virtual address) - /// - public enum RVA : uint { - } - - partial class PEExtensions { - /// - /// Align up - /// - /// this - /// Alignment - 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) => (RVA)(((uint)rva + alignment - 1) & ~(alignment - 1)); - } -} diff --git a/Plugins/dnlib/PE/Subsystem.cs b/Plugins/dnlib/PE/Subsystem.cs deleted file mode 100644 index 7f24dbc..0000000 --- a/Plugins/dnlib/PE/Subsystem.cs +++ /dev/null @@ -1,37 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.PE { - /// - /// IMAGE_OPTIONAL_HEADER.Subsystem - /// - public enum Subsystem : ushort { - /// Unknown subsystem. - Unknown = 0, - /// Image doesn't require a subsystem. - Native = 1, - /// Image runs in the Windows GUI subsystem. - WindowsGui = 2, - /// Image runs in the Windows character subsystem. - WindowsCui = 3, - /// image runs in the OS/2 character subsystem. - Os2Cui = 5, - /// image runs in the Posix character subsystem. - PosixCui = 7, - /// image is a native Win9x driver. - NativeWindows = 8, - /// Image runs in the Windows CE subsystem. - WindowsCeGui = 9, - /// - EfiApplication = 10, - /// - EfiBootServiceDriver = 11, - /// - EfiRuntimeDriver = 12, - /// - EfiRom = 13, - /// - Xbox = 14, - /// - WindowsBootApplication = 16, - } -} diff --git a/Plugins/dnlib/Protection/AddEncryptionOperation.cs b/Plugins/dnlib/Protection/AddEncryptionOperation.cs deleted file mode 100644 index 83915f4..0000000 --- a/Plugins/dnlib/Protection/AddEncryptionOperation.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace dnlib.Protection { - public class AddEncryptionOperation : IEncryptionInstruction { - - private readonly uint _xIndex; - private readonly uint _kIndex; - private readonly uint _c; - - public AddEncryptionOperation(uint xIndex, uint kIndex, uint c) { - _xIndex = xIndex; - _kIndex = kIndex % EncryptionInfo.KeyLength; - _c = c & 0xFF; - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - uint xIndex = _xIndex % length + start; - content[xIndex] = (byte)(content[xIndex] + encryptionParam[_kIndex] + _c); - } - - public string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName) { - return $"{{ uint32_t xIndex = {_xIndex} % {dataLengthVarName}; {dataVarName}[xIndex] = (byte)((uint32_t){dataVarName}[xIndex] - (uint32_t){keyVarName}[{_kIndex}] - {_c}u); }}"; - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptedModuleWriter.cs b/Plugins/dnlib/Protection/EncryptedModuleWriter.cs deleted file mode 100644 index f5e53b7..0000000 --- a/Plugins/dnlib/Protection/EncryptedModuleWriter.cs +++ /dev/null @@ -1,252 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; -using dnlib.DotNet; -using dnlib.DotNet.MD; -using dnlib.DotNet.Writer; -using dnlib.PE; -using dnlib.W32Resources; -using ImageCor20Header = dnlib.DotNet.Writer.ImageCor20Header; - -namespace dnlib.Protection { - - /// - /// - /// - public sealed class EncryptedModuleWriterOptions : ModuleWriterOptionsBase { - - public RandomEncryption encryptor; - - /// - /// Constructor - /// - /// The module - public EncryptedModuleWriterOptions(ModuleDef module) : base(module) { } - } - - /// - /// - /// - public sealed class EncryptedModuleWriter : ModuleWriterBase { - - - readonly ModuleDef module; - EncryptedModuleWriterOptions options; - List sections; - PESection textSection; - - - EncryptionHeader header; - - /// - public override ModuleDef Module => module; - - /// - public override ModuleWriterOptionsBase TheOptions => Options; - - /// - /// Gets/sets the writer options. This is never null - /// - public EncryptedModuleWriterOptions Options { - get => options ??= new EncryptedModuleWriterOptions(module); - set => options = value; - } - - /// - /// 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 - /// - public override PESection TextSection => textSection; - - /// - /// Gets the .rsrc section or null if none - /// - public override PESection RsrcSection => null; - - /// - /// Constructor - /// - /// The module - public EncryptedModuleWriter(ModuleDef module) - : this(module, null) { - } - - /// - /// Constructor - /// - /// The module - /// Options or null - public EncryptedModuleWriter(ModuleDef module, EncryptedModuleWriterOptions options) { - this.module = module; - this.options = options; - } - - /// - protected override long WriteImpl() { - try { - EncryptionContext.Encryption = options.encryptor; - Initialize(); - metadata.CreateTables(); - return WriteFile(); - } - finally { - EncryptionContext.Encryption = null; - } - } - - void Initialize() { - CreateSections(); - OnWriterEvent(ModuleWriterEvent.PESectionsCreated); - - CreateChunks(); - OnWriterEvent(ModuleWriterEvent.ChunksCreated); - - AddChunksToSections(); - OnWriterEvent(ModuleWriterEvent.ChunksAddedToSections); - } - - /// - protected override Win32Resources GetWin32Resources() { - return null; - } - - void CreateSections() { - sections = new List(); - sections.Add(textSection = new PESection(".text", 0x60000020)); - } - - void CreateChunks() { - IEncryption enc = EncryptionContext.Encryption; - header = new EncryptionHeader() { - formatVersion = 1, - encryptionInfo = new EncryptionInfo() { - algorithm = options.encryptor.Algorithm, - version = options.encryptor.AlgoVersion, - key = options.encryptor.EncParam, - headerEncOpCodes = enc.FileHeaderEnc.GetDecryptionOpCode(), - stringEncOpCodes = enc.StringEnc.GetDecryptionOpCode(), - blobEncOpCodes = enc.BlobEnc.GetDecryptionOpCode(), - userStringEncOpCodes = enc.UserStringEnc.GetDecryptionOpCode(), - lazyUserStringEncOpCodes = enc.LazyUserStringEnc.GetDecryptionOpCode(), - tableEncOpCodes = enc.TableEnc.GetDecryptionOpCode(), - lazyTableEncOpCodes = enc.LazyTableEnc.GetDecryptionOpCode(), - methodBoyEncOpCodes = enc.MethodBodyEnc.GetDecryptionOpCode(), - }, - }; - CreateMetadataChunks(module); - } - - void AddChunksToSections() { - textSection.Add(constants, DEFAULT_CONSTANTS_ALIGNMENT); - textSection.Add(methodBodies, DEFAULT_METHODBODIES_ALIGNMENT); - textSection.Add(metadata, DEFAULT_METADATA_ALIGNMENT); - } - - long WriteFile() { - //managedExportsWriter.AddExportedMethods(metadata.ExportedMethods, GetTimeDateStamp()); - //if (managedExportsWriter.HasExports) - // needStartupStub = true; - - //OnWriterEvent(ModuleWriterEvent.BeginWritePdb); - //WritePdbFile(); - //OnWriterEvent(ModuleWriterEvent.EndWritePdb); - - metadata.OnBeforeSetOffset(); - OnWriterEvent(ModuleWriterEvent.BeginCalculateRvasAndFileOffsets); - var chunks = new List(); - chunks.Add(header); - //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); - header.sections = sections; - //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"); - uint fileAlignment = 8; - uint sectionAlignment = 8; - CalculateRvasAndFileOffsets(chunks, 0, 0, fileAlignment, sectionAlignment); - OnWriterEvent(ModuleWriterEvent.EndCalculateRvasAndFileOffsets); - - InitializeChunkProperties(); - - OnWriterEvent(ModuleWriterEvent.BeginWriteChunks); - var writer = new DataWriter(destStream); - WriteChunks(writer, chunks, 0, fileAlignment); - long imageLength = writer.Position - destStreamBaseOffset; - OnWriterEvent(ModuleWriterEvent.EndWriteChunks); - - //OnWriterEvent(ModuleWriterEvent.BeginStrongNameSign); - //if (Options.StrongNameKey is not null) - // StrongNameSign((long)strongNameSignature.FileOffset); - //OnWriterEvent(ModuleWriterEvent.EndStrongNameSign); - - //OnWriterEvent(ModuleWriterEvent.BeginWritePEChecksum); - //if (Options.AddCheckSum) - // peHeaders.WriteCheckSum(writer, imageLength); - //OnWriterEvent(ModuleWriterEvent.EndWritePEChecksum); - - return imageLength; - } - - void InitializeChunkProperties() { - header.entryPointToken = GetEntryPoint(); - header.metadataRva = metadata.RVA; - header.metadataSize = metadata.GetVirtualSize(); - - //header.imageCor20Header = imageCor20Header; - //importAddressTable.ImportDirectory = importDirectory; - //importDirectory.ImportAddressTable = importAddressTable; - //startupStub.ImportDirectory = importDirectory; - //startupStub.PEHeaders = peHeaders; - //peHeaders.StartupStub = startupStub; - //peHeaders.ImageCor20Header = imageCor20Header; - //peHeaders.ImportAddressTable = importAddressTable; - //peHeaders.ImportDirectory = importDirectory; - //peHeaders.Win32Resources = win32Resources; - //peHeaders.RelocDirectory = relocDirectory; - //peHeaders.DebugDirectory = debugDirectory; - //imageCor20Header.Metadata = metadata; - //imageCor20Header.NetResources = netResources; - //imageCor20Header.StrongNameSignature = strongNameSignature; - //managedExportsWriter.InitializeChunkProperties(); - } - - uint GetEntryPoint() { - if (module.ManagedEntryPoint is MethodDef methodEntryPoint) - return new MDToken(Table.Method, metadata.GetRid(methodEntryPoint)).Raw; - //if (module.ManagedEntryPoint is FileDef fileEntryPoint) - // return new MDToken(Table.File, metadata.GetRid(fileEntryPoint)).Raw; - - //uint nativeEntryPoint = (uint)module.NativeEntryPoint; - //if (nativeEntryPoint != 0) - // return nativeEntryPoint; - - return 0; - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionContext.cs b/Plugins/dnlib/Protection/EncryptionContext.cs deleted file mode 100644 index 66a1709..0000000 --- a/Plugins/dnlib/Protection/EncryptionContext.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace dnlib.Protection { - internal class EncryptionContext { - - public const int SmallSegmentSize = 0x10; - - public const int BigSegmentSize = 0x100; - - public static IEncryption Encryption { get; set; } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionHeader.cs b/Plugins/dnlib/Protection/EncryptionHeader.cs deleted file mode 100644 index 0dd861c..0000000 --- a/Plugins/dnlib/Protection/EncryptionHeader.cs +++ /dev/null @@ -1,199 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Diagnostics; -using System.Text; -using dnlib.DotNet; -using dnlib.DotNet.Writer; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.Protection { - - - public enum Algorithm { - None, - Custom, - } - - /// - /// - /// - public class EncryptionInfo { - public const int KeyLength = 256; - - public Algorithm algorithm; - public int version; - public byte[] key; // 256 bytes - public byte[] headerEncOpCodes; - public byte[] stringEncOpCodes; - public byte[] blobEncOpCodes; - public byte[] userStringEncOpCodes; - public byte[] lazyUserStringEncOpCodes; - public byte[] tableEncOpCodes; - public byte[] lazyTableEncOpCodes; - public byte[] methodBoyEncOpCodes; - - - private static byte[] originalSignature { get; } = Encoding.UTF8.GetBytes("Hello, HybridCLR"); - - public byte[] encryptedSignature; - - /// - /// - /// - /// - public uint GetVirtualSize() => 4 - + 4 - + KeyLength - + 4 + GetAlignedLength(headerEncOpCodes) - + 4 + GetAlignedLength(stringEncOpCodes) - + 4 + GetAlignedLength(blobEncOpCodes) - + 4 + GetAlignedLength(userStringEncOpCodes) - + 4 + GetAlignedLength(lazyUserStringEncOpCodes) - + 4 + GetAlignedLength(tableEncOpCodes) - + 4 + GetAlignedLength(lazyTableEncOpCodes) - + 4 + GetAlignedLength(methodBoyEncOpCodes) - + 16; - - - public static uint GetAlignedLength(byte[] bytes) { - return (uint)((bytes.Length + 3) & ~0x3); - } - - public void WriteBytesAigned(DataWriter writer, byte[] bytes) { - writer.WriteUInt32((uint)bytes.Length); - writer.WriteBytes(bytes); - int padding = (int)(4 - (writer.Position % 4)); - if (padding != 4) { - writer.WriteBytes(new byte[padding]); - } - } - - public void WriteTo(DataWriter writer) { - writer.WriteUInt32((uint)algorithm); - writer.WriteUInt32((uint)version); - Debug.Assert(key.Length == KeyLength); - writer.WriteBytes(key); - - WriteBytesAigned(writer, headerEncOpCodes); - WriteBytesAigned(writer, stringEncOpCodes); - WriteBytesAigned(writer, blobEncOpCodes); - WriteBytesAigned(writer, userStringEncOpCodes); - WriteBytesAigned(writer, lazyUserStringEncOpCodes); - WriteBytesAigned(writer, tableEncOpCodes); - WriteBytesAigned(writer, lazyTableEncOpCodes); - WriteBytesAigned(writer, methodBoyEncOpCodes); - - encryptedSignature = CreateEncryptedSignature(); - Debug.Assert(encryptedSignature.Length == 16); - writer.WriteBytes(encryptedSignature); - } - - private byte[] CreateEncryptedSignature() { - byte[] encSig = new byte[originalSignature.Length]; - Array.Copy(originalSignature, encSig, originalSignature.Length); - EncryptionContext.Encryption.SignatureEnc.Encrypt(encSig, 0, (uint)encSig.Length, key); - return encSig; - } - } - - /// - /// - /// - public interface IBytesEncryptor { - - Algorithm Algorithm { get; } - - Int32 AlgoVersion { get; } - - byte[] Encrypt(byte[] content, byte[] encryptionParam); - - byte[] EncryptString(string content, byte[] encryptionParam); - byte[] EncryptUserString(string content, byte[] encryptionParam); - - byte[] EncryptBlob(byte[] content, byte[] encryptionParam); - } - - - - /// - /// format: - /// file magic numer := 'CDPH' - /// encryption_info := |algorithm : uint32_t | version: uint32_t | param: uint8_t[32]| signature: uint8_t[128]| - /// cli_header := | rva: uint32_t | size: uint32_t | entryPointToken: uint32_t | - /// section_count : int32_t - /// section_descs := | Section { raw_offset: uint32_t | raw_size : uint32_t | rva_start: uint32_t | virtual_size: uint32_t } | ... - /// secion_datas := | uint8_t[length] | ... - /// - public class EncryptionHeader : IChunk { - - - - public ImageCor20Header imageCor20Header; - - // ================= - - - public string fileMagic = "CDPH"; - - public int formatVersion; - - public EncryptionInfo encryptionInfo; - - public uint entryPointToken; - public RVA metadataRva; - public uint metadataSize; - - public List sections; - - - private FileOffset _fileOffset; - - - /// - /// - /// - public FileOffset FileOffset => _fileOffset; - - private RVA _rva; - public RVA RVA => _rva; - - public uint CalculateAlignment() => 4; - - private uint _length; - public uint GetFileLength() => _length; - public uint GetVirtualSize() => _length; - public void SetOffset(FileOffset offset, RVA rva) { - _fileOffset = offset; - _rva = rva; - - // compute length - _length = (uint)Encoding.UTF8.GetByteCount(fileMagic) - + 4 // formatVersion - + encryptionInfo.GetVirtualSize() // encryptionInfo - + 12 // cli header - + 4 - + 16 * (uint)sections.Count; - } - - /// - /// - /// - /// - public void WriteTo(DataWriter writer) { - writer.WriteBytes(Encoding.UTF8.GetBytes(fileMagic)); - writer.WriteInt32(formatVersion); - encryptionInfo.WriteTo(writer); - writer.WriteInt32((int)entryPointToken); - writer.WriteUInt32((uint)metadataRva); - writer.WriteUInt32(metadataSize); - writer.WriteUInt32((uint)sections.Count); - foreach(var section in sections) { - writer.WriteUInt32((uint)section.FileOffset); - writer.WriteUInt32(section.GetFileLength()); - writer.WriteUInt32((uint)section.RVA); - writer.WriteUInt32(section.GetVirtualSize()); - } - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionInstructionSet.cs b/Plugins/dnlib/Protection/EncryptionInstructionSet.cs deleted file mode 100644 index 9cd1fc5..0000000 --- a/Plugins/dnlib/Protection/EncryptionInstructionSet.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Collections.Generic; - -namespace dnlib.Protection { - public class EncryptionInstructionSet { - - private readonly int seed; - - public List Instructions { get; } = new List(); - - public int Seed => seed; - - public int Count => Instructions.Count; - - public EncryptionInstructionSet(int seed) { - this.seed = seed; - - var r = new MyRandom(seed); - int count = 256; - for (int i = 0; i < count; i++) { - Instructions.Add(EncryptionOperationFactory.CreateEncryptor(r.Next())); - } - } - - public IEncryptionInstruction GetInstruction(int opCode) { - return Instructions[opCode]; - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionMethod.cs b/Plugins/dnlib/Protection/EncryptionMethod.cs deleted file mode 100644 index 78ff77d..0000000 --- a/Plugins/dnlib/Protection/EncryptionMethod.cs +++ /dev/null @@ -1,55 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; - -namespace dnlib.Protection { - public class EncryptionMethod { - - public class InstructionInfo { - public readonly int opCode; - - public readonly IEncryptionInstruction oper; - - public InstructionInfo(int index, IEncryptionInstruction oper) { - this.opCode = index; - this.oper = oper; - } - } - - public List Insts { get; } = new List(); - - public byte[] GetDecryptionOpCode() { - return Insts.Select(e => (byte)e.opCode).Reverse().ToArray(); - } - - public EncryptionMethod(EncryptionInstructionSet re, int seed, int instCount) { - var r = new MyRandom(seed); - int instSetCount = re.Count; - for (int i = 0; i < instCount; i++) { - int index = r.Next(instSetCount); - Insts.Add(new InstructionInfo(index, re.GetInstruction(index))); - } - } - - public EncryptionMethod(EncryptionInstructionSet re, byte[] opCodes) { - foreach (byte op in opCodes) { - Insts.Add(new InstructionInfo(op, re.GetInstruction(op))); - } - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - for (int i = 0; i < Insts.Count; i++) { - Insts[i].oper.Encrypt(content, start, length, encryptionParam); - } - } - - public void EncryptBySegment(byte[] content, uint start, uint length, byte[] encryptionParam, uint segmentSize) { - for (uint i = 0; i < length; i += segmentSize) { - uint len = Math.Min(segmentSize, length - i); - foreach (var inst in Insts) { - inst.oper.Encrypt(content, start + i, len, encryptionParam); - } - } - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionOperationFactory.cs b/Plugins/dnlib/Protection/EncryptionOperationFactory.cs deleted file mode 100644 index 9966908..0000000 --- a/Plugins/dnlib/Protection/EncryptionOperationFactory.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace dnlib.Protection { - public class EncryptionOperationFactory { - - public static IEncryptionInstruction CreateEncryptor(int seed) { - var r = new MyRandom(seed); - EncryptionOperationType type = (EncryptionOperationType)r.Next((int)EncryptionOperationType.MaxTypeValue); - var sr = new MyRandom(r.Next()); - switch (type) { - case EncryptionOperationType.Xor: { - return new XorEncryptionOperation(sr.NextU(), sr.NextU(), sr.NextU()); - } - case EncryptionOperationType.Add: { - return new AddEncryptionOperation(sr.NextU(), sr.NextU(), sr.NextU()); - } - case EncryptionOperationType.Permute: { - return new PermuteEncryptionOperation(sr.NextU(), sr.NextU(), sr.NextU()); - } - case EncryptionOperationType.Permute2: { - return new Permute2EncryptionOperation(sr.NextU(), sr.NextU(), sr.NextU()); - } - case EncryptionOperationType.RotateLeftShift: { - return new RotateLeftShiftEncryptionOperation(sr.NextU(), sr.NextU(), sr.NextU()); - } - } - return null; - } - } -} diff --git a/Plugins/dnlib/Protection/EncryptionOperationType.cs b/Plugins/dnlib/Protection/EncryptionOperationType.cs deleted file mode 100644 index 38cc205..0000000 --- a/Plugins/dnlib/Protection/EncryptionOperationType.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace dnlib.Protection { - public enum EncryptionOperationType { - Xor, - Add, - Permute, - Permute2, - RotateLeftShift, - MaxTypeValue, - } -} diff --git a/Plugins/dnlib/Protection/EncryptionVMInterpreterGenerator.cs b/Plugins/dnlib/Protection/EncryptionVMInterpreterGenerator.cs deleted file mode 100644 index 7cb3954..0000000 --- a/Plugins/dnlib/Protection/EncryptionVMInterpreterGenerator.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace dnlib.Protection { - //public class EncryptionVMInterpreterGenerator { - - // private readonly EncryptionInstructionSet _encryptionInstructionSet; - - // public EncryptionVMInterpreterGenerator(EncryptionInstructionSet encryptionInstructionSet) { - // _encryptionInstructionSet = encryptionInstructionSet; - // } - - // public void Generate(string templateFile, string outputFile) { - // var sb = new StringBuilder(); - - // int opCode = 0; - // foreach (var inst in _encryptionInstructionSet.opers) { - // sb.Append($"\t\t\tcase {opCode}:").Append(inst.GenerateDecryptExpression("data", "dataLength", "key")).Append("break;").AppendLine(); - // ++opCode; - // } - - // var template = System.IO.File.ReadAllText(templateFile); - // var frr = new FileRegionReplace(template); - // frr.Replace("INSTRUCTIONS", sb.ToString()); - // frr.Commit(outputFile); - // } - //} -} diff --git a/Plugins/dnlib/Protection/FileRegionReplace.cs b/Plugins/dnlib/Protection/FileRegionReplace.cs deleted file mode 100644 index c505e33..0000000 --- a/Plugins/dnlib/Protection/FileRegionReplace.cs +++ /dev/null @@ -1,76 +0,0 @@ -//using System; -//using System.Collections.Generic; -//using System.IO; - -//namespace dnlib.Protection -//{ -// public class FileRegionReplace -// { -// private readonly string _tplCode; - -// private readonly Dictionary _regionReplaceContents = new Dictionary(); - -// public FileRegionReplace(string tplCode) -// { -// _tplCode = tplCode; -// } - -// public void Replace(string regionName, string regionContent) -// { -// _regionReplaceContents.Add(regionName, regionContent); -// } - -// public string GenFinalString() -// { -// string originContent = _tplCode; - -// string resultContent = originContent; - -// foreach (var c in _regionReplaceContents) -// { -// resultContent = ReplaceRegion(resultContent, c.Key, c.Value); -// } -// return resultContent; -// } - -// public void Commit(string outputFile) -// { -// string dir = Path.GetDirectoryName(outputFile); -// Directory.CreateDirectory(dir); -// string resultContent = GenFinalString(); -// if (File.Exists(outputFile) && File.ReadAllText(outputFile) == resultContent) -// { -// Console.WriteLine("===>>>" + outputFile + " not change"); -// return; -// } -// var utf8WithoutBOM = new System.Text.UTF8Encoding(false); -// File.WriteAllText(outputFile, resultContent, utf8WithoutBOM); -// } - -// public static string ReplaceRegion(string resultText, string region, string replaceContent) -// { -// int startIndex = resultText.IndexOf("//!!!{{" + region); -// if (startIndex == -1) -// { -// throw new Exception($"region:{region} start not find"); -// } -// int endIndex = resultText.IndexOf("//!!!}}" + region); -// if (endIndex == -1) -// { -// throw new Exception($"region:{region} end not find"); -// } -// int replaceStart = resultText.IndexOf('\n', startIndex); -// int replaceEnd = resultText.LastIndexOf('\n', endIndex); -// if (replaceStart == -1 || replaceEnd == -1) -// { -// throw new Exception($"region:{region} not find"); -// } -// if (resultText.Substring(replaceStart, replaceEnd - replaceStart) == replaceContent) -// { -// return resultText; -// } -// resultText = resultText.Substring(0, replaceStart) + "\n" + replaceContent + "\n" + resultText.Substring(replaceEnd); -// return resultText; -// } -// } -//} diff --git a/Plugins/dnlib/Protection/IEncryption.cs b/Plugins/dnlib/Protection/IEncryption.cs deleted file mode 100644 index 9f8f404..0000000 --- a/Plugins/dnlib/Protection/IEncryption.cs +++ /dev/null @@ -1,28 +0,0 @@ -namespace dnlib.Protection { - public interface IEncryption { - - byte[] EncParam { get; } - - Algorithm Algorithm { get; } - - int AlgoVersion { get; } - - EncryptionMethod SignatureEnc { get; } - - EncryptionMethod FileHeaderEnc { get; } - - EncryptionMethod StringEnc { get; } - - EncryptionMethod BlobEnc { get; } - - EncryptionMethod UserStringEnc { get; } - - EncryptionMethod LazyUserStringEnc { get; } - - EncryptionMethod TableEnc { get; } - - EncryptionMethod LazyTableEnc { get; } - - EncryptionMethod MethodBodyEnc { get; } - } -} diff --git a/Plugins/dnlib/Protection/IEncryptionInstruction.cs b/Plugins/dnlib/Protection/IEncryptionInstruction.cs deleted file mode 100644 index 456bab0..0000000 --- a/Plugins/dnlib/Protection/IEncryptionInstruction.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace dnlib.Protection { - public interface IEncryptionInstruction { - void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam); - - string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName); - } -} diff --git a/Plugins/dnlib/Protection/MyRandom.cs b/Plugins/dnlib/Protection/MyRandom.cs deleted file mode 100644 index e540384..0000000 --- a/Plugins/dnlib/Protection/MyRandom.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace dnlib.Protection { - public class MyRandom { - private int _seed; - - public MyRandom(int seed) { - _seed = seed; - } - - public int Next() { - // linear congruential generator - _seed = 214013 * _seed + 2531011; - return _seed; - } - - public uint NextU() { - return (uint)Next(); - } - - public int Next(int maxValue) { - return (int)((uint)Next() % (uint)maxValue); - } - } -} diff --git a/Plugins/dnlib/Protection/NullEncryptior.cs b/Plugins/dnlib/Protection/NullEncryptior.cs deleted file mode 100644 index 3c078ad..0000000 --- a/Plugins/dnlib/Protection/NullEncryptior.cs +++ /dev/null @@ -1,33 +0,0 @@ -using System.Text; -using dnlib.Protection; - -namespace dnlib.Protection { - - /// - /// - /// - public class NullEncryptior : IBytesEncryptor { - - /// - /// - /// - public Algorithm Algorithm => Algorithm.None; - - public int AlgoVersion => 1; - - public byte[] Encrypt(byte[] content, byte[] encryptionParam) { - return content; - } - - public byte[] EncryptBlob(byte[] content, byte[] encryptionParam) { - return Encrypt(content, encryptionParam); - } - public byte[] EncryptString(string content, byte[] encryptionParam) { - return Encrypt(Encoding.UTF8.GetBytes(content), encryptionParam); - } - - public byte[] EncryptUserString(string content, byte[] encryptionParam) { - return EncryptString(content, encryptionParam); - } - } -} diff --git a/Plugins/dnlib/Protection/Permute2EncryptionOperation.cs b/Plugins/dnlib/Protection/Permute2EncryptionOperation.cs deleted file mode 100644 index d0ea857..0000000 --- a/Plugins/dnlib/Protection/Permute2EncryptionOperation.cs +++ /dev/null @@ -1,27 +0,0 @@ -namespace dnlib.Protection { - public class Permute2EncryptionOperation : IEncryptionInstruction { - - private readonly uint _xIndex1; - private readonly uint _kIndex; - private readonly uint _c; - - public Permute2EncryptionOperation(uint xIndex1, uint kIndex, uint c) { - _xIndex1 = xIndex1; - _kIndex = kIndex % EncryptionInfo.KeyLength; - _c = c; - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - uint xIndex1 = _xIndex1 % length + start; - uint xIndex2 = (encryptionParam[_kIndex] + _c) % length + start; - byte a = (byte)(content[xIndex1] + content[xIndex2]); - byte b = (byte)(content[xIndex2] + 1); - content[xIndex1] = a; - content[xIndex2] = b; - } - - public string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName) { - return $"{{ uint32_t xIndex1 = {_xIndex1} % {dataLengthVarName}; uint32_t xIndex2 = ((uint32_t){keyVarName}[{_kIndex}] + {_c}u) % {dataLengthVarName}; byte a = {dataVarName}[xIndex1]; byte b = {dataVarName}[xIndex2] - 1; {dataVarName}[xIndex1] = a - b; {dataVarName}[xIndex2] = b; }}"; - } - } -} diff --git a/Plugins/dnlib/Protection/PermuteEncryptionOperation.cs b/Plugins/dnlib/Protection/PermuteEncryptionOperation.cs deleted file mode 100644 index 3ce9b0a..0000000 --- a/Plugins/dnlib/Protection/PermuteEncryptionOperation.cs +++ /dev/null @@ -1,26 +0,0 @@ -namespace dnlib.Protection { - public class PermuteEncryptionOperation : IEncryptionInstruction { - - private readonly uint _xIndex1; - private readonly uint _kIndex; - private readonly uint _c; - - public PermuteEncryptionOperation(uint xIndex1, uint kIndex, uint c) { - _xIndex1 = xIndex1; - _kIndex = kIndex % EncryptionInfo.KeyLength; - _c = c; - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - uint xIndex1 = _xIndex1 % length + start; - uint xIndex2 = (encryptionParam[_kIndex] + _c) % length + start; - byte temp = content[xIndex1]; - content[xIndex1] = content[xIndex2]; - content[xIndex2] = temp; - } - - public string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName) { - return $"{{ uint32_t xIndex1 = {_xIndex1} % {dataLengthVarName}; uint32_t xIndex2 = ((uint32_t){keyVarName}[{_kIndex}] + {_c}u) % {dataLengthVarName}; byte temp = {dataVarName}[xIndex1]; {dataVarName}[xIndex1] = {dataVarName}[xIndex2]; {dataVarName}[xIndex2] = temp; }}"; - } - } -} diff --git a/Plugins/dnlib/Protection/RandomEncryption.cs b/Plugins/dnlib/Protection/RandomEncryption.cs deleted file mode 100644 index 0adc22e..0000000 --- a/Plugins/dnlib/Protection/RandomEncryption.cs +++ /dev/null @@ -1,103 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.RegularExpressions; - -namespace dnlib.Protection { - - public class RandomEncryptionOptions { - - public int InstructionSeed { get; set; } - - public int MetadataSeed { get; set; } - - public byte[] EncKey { get; set; } - - public int StringEncCodeLength { get; set; } = 128; - - public int BlobEncCodeLength { get; set; } = 128; - - public int UserStringEncCodeLength { get; set; } = 128; - - public int LazyUserStringEncCodeLength { get; set; } = 16; - - public int TableEncCodeLength { get; set; } = 128; - - public int LazyTableEncCodeLength { get; set; } = 16; - - public int MethodBodyEncCodeLength { get; set; } = 16; - } - - - public class RandomEncryption : IEncryption { - - private readonly byte[] _encParam; - - private readonly EncryptionInstructionSet _instructionSet; - - private readonly EncryptionMethod _signatureEnc; - - private readonly EncryptionMethod _fileHeaderEnc; - private readonly EncryptionMethod _stringEnc; - private readonly EncryptionMethod _blobEnc; - private readonly EncryptionMethod _userStringEnc; - private readonly EncryptionMethod _lazyUserStringEnc; - private readonly EncryptionMethod _tableEnc; - private readonly EncryptionMethod _lazyTableEnc; - private readonly EncryptionMethod _methodBodyEnc; - - public byte[] EncParam => _encParam; - - public Algorithm Algorithm => Algorithm.Custom; - - public int AlgoVersion => 0; - - public EncryptionInstructionSet InstructionSet => _instructionSet; - - public EncryptionMethod SignatureEnc => _signatureEnc; - - public EncryptionMethod FileHeaderEnc => _fileHeaderEnc; - - public EncryptionMethod StringEnc => _stringEnc; - - public EncryptionMethod BlobEnc => _blobEnc; - - public EncryptionMethod UserStringEnc => _userStringEnc; - - public EncryptionMethod LazyUserStringEnc => _lazyUserStringEnc; - - public EncryptionMethod TableEnc => _tableEnc; - - public EncryptionMethod LazyTableEnc => _lazyTableEnc; - - public EncryptionMethod MethodBodyEnc => _methodBodyEnc; - - public RandomEncryption(RandomEncryptionOptions opt) { - _encParam = opt.EncKey; - - _instructionSet = new EncryptionInstructionSet(opt.InstructionSeed); - - _signatureEnc = new EncryptionMethod(_instructionSet, CreateSignatureEncOpCodes()); - - int metadataSeed = opt.MetadataSeed; - _fileHeaderEnc = new EncryptionMethod(_instructionSet, metadataSeed++, 0x100); - _stringEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.StringEncCodeLength); - _blobEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.BlobEncCodeLength); - _userStringEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.UserStringEncCodeLength); - _lazyUserStringEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.LazyUserStringEncCodeLength); - _tableEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.TableEncCodeLength); - _lazyTableEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.LazyTableEncCodeLength); - _methodBodyEnc = new EncryptionMethod(_instructionSet, metadataSeed++, opt.MethodBodyEncCodeLength); - } - - private byte[] CreateSignatureEncOpCodes() { - int size = 256; - var ops = new byte[size]; - for (int i = 0; i < ops.Length; i++) { - ops[i] = (byte)i; - } - return ops; - } - } -} diff --git a/Plugins/dnlib/Protection/RotateLeftShiftEncryptionOperation.cs b/Plugins/dnlib/Protection/RotateLeftShiftEncryptionOperation.cs deleted file mode 100644 index 2daf0c4..0000000 --- a/Plugins/dnlib/Protection/RotateLeftShiftEncryptionOperation.cs +++ /dev/null @@ -1,25 +0,0 @@ -namespace dnlib.Protection { - public class RotateLeftShiftEncryptionOperation : IEncryptionInstruction { - - private readonly uint _xIndex; - private readonly uint _kIndex; - private readonly uint _c; - - public RotateLeftShiftEncryptionOperation(uint xIndex, uint kIndex, uint c) { - _xIndex = xIndex; - _kIndex = kIndex % EncryptionInfo.KeyLength; - _c = c; - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - uint xIndex = _xIndex % length + start; - int shift = (int)((encryptionParam[_kIndex] + _c) % 8); - uint v = content[xIndex]; - content[xIndex] = (byte)((v << shift) | (v >> (8 - shift))); - } - - public string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName) { - return $"{{ uint32_t xIndex = {_xIndex} % {dataLengthVarName}; uint32_t shift = (uint32_t)({keyVarName}[{_kIndex}] + {_c}u) % 8; {dataVarName}[xIndex] = (byte)(((uint32_t){dataVarName}[xIndex] >> shift) | ((uint32_t){dataVarName}[xIndex] << (8 - shift))); }}"; - } - } -} diff --git a/Plugins/dnlib/Protection/XorEncryptionOperation.cs b/Plugins/dnlib/Protection/XorEncryptionOperation.cs deleted file mode 100644 index a330a86..0000000 --- a/Plugins/dnlib/Protection/XorEncryptionOperation.cs +++ /dev/null @@ -1,23 +0,0 @@ -namespace dnlib.Protection { - public class XorEncryptionOperation : IEncryptionInstruction { - - private readonly uint _xIndex; - private readonly uint _kIndex; - private readonly uint _c; - - public XorEncryptionOperation(uint xIndex, uint kIndex, uint c) { - _xIndex = xIndex; - _kIndex = kIndex % EncryptionInfo.KeyLength; - _c = c & 0xFF; - } - - public void Encrypt(byte[] content, uint start, uint length, byte[] encryptionParam) { - uint xIndex = (_xIndex % length) + start; - content[xIndex] = (byte)(content[xIndex] ^ encryptionParam[_kIndex] ^ _c); - } - - public string GenerateDecryptExpression(string dataVarName, string dataLengthVarName, string keyVarName) { - return $"{{ uint32_t xIndex = {_xIndex} % {dataLengthVarName}; {dataVarName}[xIndex] = (byte)((uint32_t){dataVarName}[xIndex] ^ (uint32_t){keyVarName}[{_kIndex}] ^ {_c}u); }}"; - } - } -} diff --git a/Plugins/dnlib/Settings.cs b/Plugins/dnlib/Settings.cs deleted file mode 100644 index 5b3af88..0000000 --- a/Plugins/dnlib/Settings.cs +++ /dev/null @@ -1,21 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib { - /// - /// dnlib settings - /// - public static class Settings { - /// - /// true if dnlib is thread safe. (THREAD_SAFE was defined during compilation) - /// - public static bool IsThreadSafe { - get { -#if THREAD_SAFE - return true; -#else - return false; -#endif - } - } - } -} diff --git a/Plugins/dnlib/Threading/ICancellationToken.cs b/Plugins/dnlib/Threading/ICancellationToken.cs deleted file mode 100644 index 8558f12..0000000 --- a/Plugins/dnlib/Threading/ICancellationToken.cs +++ /dev/null @@ -1,15 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.Threading { - /// - /// Cancellation token interface - /// - public interface ICancellationToken { - /// - /// Throws a if the operation should be canceled - /// - void ThrowIfCancellationRequested(); - } -} diff --git a/Plugins/dnlib/Threading/Lock.cs b/Plugins/dnlib/Threading/Lock.cs deleted file mode 100644 index 0a84755..0000000 --- a/Plugins/dnlib/Threading/Lock.cs +++ /dev/null @@ -1,91 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Runtime.Serialization; -using System.Threading; - -namespace dnlib.Threading { -#if THREAD_SAFE - [Serializable] - class LockException : Exception { - public LockException() { - } - - public LockException(string msg) - : base(msg) { - } - - protected LockException(SerializationInfo info, StreamingContext context) - : base(info, context) { - } - } - - /// - /// 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. - /// - class Lock { - readonly object lockObj; - int recurseCount; - - /// - /// Creates a new instance of this class - /// - /// - public static Lock Create() => new Lock(); - - /// - /// Constructor - /// - Lock() { - lockObj = new object(); - recurseCount = 0; - } - - /// - /// Enter read mode - /// - public void EnterReadLock() { - Monitor.Enter(lockObj); - if (recurseCount != 0) { - Monitor.Exit(lockObj); - throw new LockException("Recursive locks aren't supported"); - } - recurseCount++; - } - - /// - /// Exit read mode - /// - public void ExitReadLock() { - if (recurseCount <= 0) - throw new LockException("Too many exit lock method calls"); - recurseCount--; - Monitor.Exit(lockObj); - } - - /// - /// Enter write mode - /// - public void EnterWriteLock() { - Monitor.Enter(lockObj); - if (recurseCount != 0) { - Monitor.Exit(lockObj); - throw new LockException("Recursive locks aren't supported"); - } - recurseCount--; - } - - /// - /// Exit write mode - /// - public void ExitWriteLock() { - if (recurseCount >= 0) - throw new LockException("Too many exit lock method calls"); - recurseCount++; - Monitor.Exit(lockObj); - } - } -#endif -} diff --git a/Plugins/dnlib/Utils/ArrayEmpty.cs b/Plugins/dnlib/Utils/ArrayEmpty.cs deleted file mode 100644 index f056fc3..0000000 --- a/Plugins/dnlib/Utils/ArrayEmpty.cs +++ /dev/null @@ -1,12 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -// System namespace so it can easily be replaced with Array.Empty later -namespace System { - static class Array2 { - public static T[] Empty() => EmptyClass.Empty; - - static class EmptyClass { - public static readonly T[] Empty = new T[0]; - } - } -} diff --git a/Plugins/dnlib/Utils/CollectionDebugView.cs b/Plugins/dnlib/Utils/CollectionDebugView.cs deleted file mode 100644 index d56d09d..0000000 --- a/Plugins/dnlib/Utils/CollectionDebugView.cs +++ /dev/null @@ -1,35 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.DotNet; -using dnlib.DotNet.Emit; - -namespace dnlib.Utils { - class CollectionDebugView { - readonly ICollection list; - public CollectionDebugView(ICollection list) => this.list = list ?? throw new ArgumentNullException(nameof(list)); - - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - public TValue[] Items { - get { - var array = new TValue[list.Count]; - list.CopyTo(array, 0); - return array; - } - } - } - - 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/Plugins/dnlib/Utils/EncryptionUtil.cs b/Plugins/dnlib/Utils/EncryptionUtil.cs deleted file mode 100644 index b18f5ef..0000000 --- a/Plugins/dnlib/Utils/EncryptionUtil.cs +++ /dev/null @@ -1,44 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Text; -using dnlib.DotNet.Writer; -using dnlib.Protection; - -namespace dnlib.Utils { - internal static class EncryptionUtil { - - public static void WriteWithEncIfNeed(this DataWriter writer, Action writeAction, Func encGetter, uint segmentSize) { - IEncryption enc = EncryptionContext.Encryption; - EncryptionMethod method = enc != null ? encGetter(enc) : null; - if (method == null) { - writeAction(writer); - } else { - var ms = new MemoryStream(); - var dw = new DataWriter(ms); - writeAction(dw); - ms.Flush(); - var content = ms.ToArray(); - method.EncryptBySegment(content, 0, (uint)content.Length, enc.EncParam, segmentSize); - writer.WriteBytes(content); - } - } - - public static void WriteWithNotSegmentEncIfNeed(this DataWriter writer, Action writeAction, Func encGetter) { - IEncryption enc = EncryptionContext.Encryption; - EncryptionMethod method = enc != null ? encGetter(enc) : null; - if (method == null) { - writeAction(writer); - } - else { - var ms = new MemoryStream(); - var dw = new DataWriter(ms); - writeAction(dw); - ms.Flush(); - var content = ms.ToArray(); - method.Encrypt(content, 0, (uint)content.Length, enc.EncParam); - writer.WriteBytes(content); - } - } - } -} diff --git a/Plugins/dnlib/Utils/ILazyList.cs b/Plugins/dnlib/Utils/ILazyList.cs deleted file mode 100644 index 00c3d26..0000000 --- a/Plugins/dnlib/Utils/ILazyList.cs +++ /dev/null @@ -1,12 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System.Collections.Generic; - -namespace dnlib.Utils { - /// - /// Interface to access a lazily initialized list - /// - /// Type to store in list - interface ILazyList : IList { - } -} diff --git a/Plugins/dnlib/Utils/LazyList.cs b/Plugins/dnlib/Utils/LazyList.cs deleted file mode 100644 index 31a4d10..0000000 --- a/Plugins/dnlib/Utils/LazyList.cs +++ /dev/null @@ -1,529 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections; -using System.Collections.Generic; -using System.Diagnostics; -using dnlib.Threading; - -namespace dnlib.Utils { - /// - /// Gets notified of list events - /// - /// List value - public interface IListListener { - /// - /// Called before a new value is lazily added to the list. - /// - /// If you must access this list, you can only call _NoLock() methods - /// since a write lock is now held by this thread. - /// Index where the value will be added - /// Value that will be added to the list. It can be modified by - /// the callee. - void OnLazyAdd(int index, ref TListValue value); - - /// - /// Called before a new value is added to the list. - /// - /// If you must access this list, you can only call _NoLock() methods - /// since a write lock is now held by this thread. - /// Index where the value will be added - /// Value that will be added to the list - void OnAdd(int index, TListValue value); - - /// - /// Called before a value is removed from the list. If all elements are removed, - /// is called, and this method is not called. - /// - /// If you must access this list, you can only call _NoLock() methods - /// since a write lock is now held by this thread. - /// Index of value - /// The value that will be removed - void OnRemove(int index, TListValue value); - - /// - /// Called after the list has been resized (eg. an element has been added/removed). It's not - /// called when an element is replaced. - /// - /// If you must access this list, you can only call _NoLock() methods - /// since a write lock is now held by this thread. - /// Index where the change occurred. - void OnResize(int index); - - /// - /// Called before the whole list is cleared. - /// - /// If you must access this list, you can only call _NoLock() methods - /// since a write lock is now held by this thread. - void OnClear(); - } - - /// - /// Implements a that is lazily initialized - /// - /// Type to store in list - [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(CollectionDebugView<>))] - public class LazyList : ILazyList where TValue : class { - private protected readonly List list; - int id = 0; - private protected readonly IListListener listener; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - /// Stores a simple value - /// - private protected class Element { - protected TValue value; - - /// - /// true if it has been initialized, false otherwise - /// - public virtual bool IsInitialized_NoLock => true; - - /// - /// Default constructor - /// - protected Element() { - } - - /// - /// Constructor that should be used when new elements are inserted into - /// - /// User data - public Element(TValue data) => value = data; - - /// - /// Gets the value - /// - /// Index in the list - 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 override string ToString() => value?.ToString() ?? string.Empty; - } - - /// - public int Count { - get { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return Count_NoLock; -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - } - - /// - internal int Count_NoLock => list.Count; - - /// - public bool IsReadOnly => false; - - /// - public TValue this[int index] { - get { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return Get_NoLock(index); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - set { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - Set_NoLock(index, value); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - } - - internal TValue Get_NoLock(int index) => list[index].GetValue_NoLock(index); - - void Set_NoLock(int index, TValue value) { - if (listener is not null) { - listener.OnRemove(index, list[index].GetValue_NoLock(index)); - listener.OnAdd(index, value); - } - list[index].SetValue_NoLock(index, value); - id++; - } - - /// - /// Default constructor - /// - public LazyList() - : this(null) { - } - - /// - /// Constructor - /// - /// List listener - public LazyList(IListListener listener) { - this.listener = listener; - list = new List(); - } - - private protected LazyList(int length, IListListener listener) { - this.listener = listener; - list = new List(length); - } - - /// - public int IndexOf(TValue item) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return IndexOf_NoLock(item); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - int IndexOf_NoLock(TValue item) { - for (int i = 0; i < list.Count; i++) { - if (list[i].GetValue_NoLock(i) == item) - return i; - } - return -1; - } - - /// - public void Insert(int index, TValue item) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - Insert_NoLock(index, item); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - void Insert_NoLock(int index, TValue item) { - if (listener is not null) - listener.OnAdd(index, item); - list.Insert(index, new Element(item)); - if (listener is not null) - listener.OnResize(index); - id++; - } - - /// - public void RemoveAt(int index) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - RemoveAt_NoLock(index); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - void RemoveAt_NoLock(int index) { - if (listener is not null) - listener.OnRemove(index, list[index].GetValue_NoLock(index)); - list.RemoveAt(index); - if (listener is not null) - listener.OnResize(index); - id++; - } - - /// - public void Add(TValue item) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - Add_NoLock(item); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - void Add_NoLock(TValue item) { - int index = list.Count; - if (listener is not null) - listener.OnAdd(index, item); - list.Add(new Element(item)); - if (listener is not null) - listener.OnResize(index); - id++; - } - - /// - public void Clear() { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - Clear_NoLock(); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - void Clear_NoLock() { - if (listener is not null) - listener.OnClear(); - list.Clear(); - if (listener is not null) - listener.OnResize(0); - id++; - } - - /// - public bool Contains(TValue item) => IndexOf(item) >= 0; - - /// - public void CopyTo(TValue[] array, int arrayIndex) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - CopyTo_NoLock(array, arrayIndex); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - void CopyTo_NoLock(TValue[] array, int arrayIndex) { - for (int i = 0; i < list.Count; i++) - array[arrayIndex + i] = list[i].GetValue_NoLock(i); - } - - /// - public bool Remove(TValue item) { -#if THREAD_SAFE - theLock.EnterWriteLock(); try { -#endif - return Remove_NoLock(item); -#if THREAD_SAFE - } finally { theLock.ExitWriteLock(); } -#endif - } - - bool Remove_NoLock(TValue item) { - int index = IndexOf_NoLock(item); - if (index < 0) - return false; - RemoveAt_NoLock(index); - return true; - } - - internal bool IsInitialized(int index) { -#if THREAD_SAFE - theLock.EnterReadLock(); try { -#endif - return IsInitialized_NoLock(index); -#if THREAD_SAFE - } finally { theLock.ExitReadLock(); } -#endif - } - - bool IsInitialized_NoLock(int index) { - if ((uint)index >= (uint)list.Count) - return false; - return list[index].IsInitialized_NoLock; - } - - /// - /// Enumerator - /// - public struct Enumerator : IEnumerator { - readonly LazyList list; - readonly int id; - int index; - TValue current; - - internal Enumerator(LazyList list) { - this.list = list; - index = 0; - current = default; -#if THREAD_SAFE - list.theLock.EnterReadLock(); try { -#endif - id = list.id; -#if THREAD_SAFE - } finally { list.theLock.ExitReadLock(); } -#endif - } - - /// - /// Gets the current value - /// - public TValue Current => current; - object IEnumerator.Current => current; - - /// - /// Moves to the next element in the collection - /// - /// - public bool MoveNext() { -#if THREAD_SAFE - list.theLock.EnterWriteLock(); try { -#endif - if (list.id == id && index < list.Count_NoLock) { - current = list.list[index].GetValue_NoLock(index); - index++; - return true; - } - else - return MoveNextDoneOrThrow_NoLock(); -#if THREAD_SAFE - } finally { list.theLock.ExitWriteLock(); } -#endif - } - - bool MoveNextDoneOrThrow_NoLock() { - if (list.id != id) - throw new InvalidOperationException("List was modified"); - current = default; - return false; - } - - /// - /// Disposes the enumerator - /// - public void Dispose() { } - - void IEnumerator.Reset() => throw new NotSupportedException(); - } - - /// - /// Gets the list enumerator - /// - /// - public Enumerator GetEnumerator() => new Enumerator(this); - - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - - internal IEnumerable GetEnumerable_NoLock() { - int id2 = id; - for (int i = 0; i < list.Count; i++) { - if (id != id2) - throw new InvalidOperationException("List was modified"); - yield return list[i].GetValue_NoLock(i); - } - } - - /// - IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); - } - - /// - /// Implements a that is lazily initialized - /// - /// Type to store in list - /// Type of the context passed to the read-value delegate - [DebuggerDisplay("Count = {Count}")] - [DebuggerTypeProxy(typeof(CollectionDebugView<,>))] - public class LazyList : LazyList, ILazyList where TValue : class { - /*readonly*/ TContext context; - readonly Func readOriginalValue; - - /// - /// Stores data and keeps track of the original index and whether the data has been - /// initialized or not. - /// - sealed class LazyElement : Element { - internal readonly int origIndex; - LazyList lazyList; - - /// - public override bool IsInitialized_NoLock => lazyList is null; - - /// - public override TValue GetValue_NoLock(int index) { - if (lazyList is not null) { - value = lazyList.ReadOriginalValue_NoLock(index, origIndex); - lazyList = null; - } - return value; - } - - /// - public override void SetValue_NoLock(int index, TValue value) { - this.value = value; - lazyList = null; - } - - /// - /// Constructor that should only be called when is initialized. - /// - /// Original index of this element - /// LazyList instance - public LazyElement(int origIndex, LazyList lazyList) { - this.origIndex = origIndex; - this.lazyList = lazyList; - } - - /// - public override string ToString() { - if (lazyList is not null) { - value = lazyList.ReadOriginalValue_NoLock(this); - lazyList = null; - } - return value is null ? string.Empty : value.ToString(); - } - } - - /// - /// Default constructor - /// - public LazyList() : this(null) { - } - - /// - /// Constructor - /// - /// List listener - public LazyList(IListListener listener) : base(listener) { - } - - /// - /// Constructor - /// - /// Initial length of the list - /// Context passed to - /// Delegate instance that returns original values - public LazyList(int length, TContext context, Func readOriginalValue) - : this(length, null, context, readOriginalValue) { - } - - /// - /// Constructor - /// - /// Initial length of the list - /// List listener - /// Context passed to - /// Delegate instance that returns original values - public LazyList(int length, IListListener listener, TContext context, Func readOriginalValue) : base(length, listener) { - this.context = context; - this.readOriginalValue = readOriginalValue; - for (int i = 0; i < length; i++) - list.Add(new LazyElement(i, this)); - } - - TValue ReadOriginalValue_NoLock(LazyElement elem) => ReadOriginalValue_NoLock(list.IndexOf(elem), elem.origIndex); - - TValue ReadOriginalValue_NoLock(int index, int origIndex) { - var newValue = readOriginalValue(context, origIndex); - listener?.OnLazyAdd(index, ref newValue); - return newValue; - } - } -} diff --git a/Plugins/dnlib/Utils/SimpleLazyList.cs b/Plugins/dnlib/Utils/SimpleLazyList.cs deleted file mode 100644 index 592aaff..0000000 --- a/Plugins/dnlib/Utils/SimpleLazyList.cs +++ /dev/null @@ -1,108 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using System.Threading; -using dnlib.DotNet; - -namespace dnlib.Utils { - /// - /// A readonly list that gets initialized lazily - /// - /// Any class type - [DebuggerDisplay("Count = {Length}")] - sealed class SimpleLazyList where T : class { - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - readonly T[] elements; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly Func readElementByRID; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly uint length; - - /// - /// Gets the length of this list - /// - public uint Length => length; - - /// - /// Access the list - /// - /// Index - /// The element or null if is invalid - public T this[uint index] { - get { - if (index >= length) - return null; - if (elements[index] is null) - Interlocked.CompareExchange(ref elements[index], readElementByRID(index + 1), null); - return elements[index]; - } - } - - /// - /// Constructor - /// - /// Length of the list - /// Delegate instance that lazily reads an element. It might - /// be called more than once for each rid in rare cases. It must never return - /// null. - public SimpleLazyList(uint length, Func readElementByRID) { - this.length = length; - this.readElementByRID = readElementByRID; - elements = new T[length]; - } - } - - /// - /// A readonly list that gets initialized lazily - /// - /// Any class type - [DebuggerDisplay("Count = {Length}")] - sealed class SimpleLazyList2 where T : class, IContainsGenericParameter2 { - [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)] - readonly T[] elements; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly Func readElementByRID; - [DebuggerBrowsable(DebuggerBrowsableState.Never)] - readonly uint length; - - /// - /// Gets the length of this list - /// - public uint Length => length; - - /// - /// Access the list - /// - /// Index - /// Generic parameter context - /// The element or null if is invalid - public T this[uint index, GenericParamContext gpContext] { - get { - if (index >= length) - return 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. - if (elem.ContainsGenericParameter) - return elem; - Interlocked.CompareExchange(ref elements[index], elem, null); - } - return elements[index]; - } - } - - /// - /// Constructor - /// - /// Length of the list - /// Delegate instance that lazily reads an element. It might - /// be called more than once for each rid. It must never return null. - public SimpleLazyList2(uint length, Func readElementByRID) { - this.length = length; - this.readElementByRID = readElementByRID; - elements = new T[length]; - } - } -} diff --git a/Plugins/dnlib/Utils/UserValue.cs b/Plugins/dnlib/Utils/UserValue.cs deleted file mode 100644 index c0114ba..0000000 --- a/Plugins/dnlib/Utils/UserValue.cs +++ /dev/null @@ -1,105 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Diagnostics; -using dnlib.Threading; - -namespace dnlib.Utils { - /// - /// Lazily returns the original value if the user hasn't overwritten the value - /// - /// Value type - [DebuggerDisplay("{value}")] - struct UserValue { -#if THREAD_SAFE - Lock theLock; -#endif - Func readOriginalValue; - TValue value; - bool isUserValue; - bool isValueInitialized; - -#if THREAD_SAFE - /// - /// Sets the lock that protects the data - /// - public Lock Lock { - set => theLock = value; - } -#endif - - /// - /// Set a delegate instance that will return the original value - /// - public Func ReadOriginalValue { - set => readOriginalValue = value; - } - - /// - /// Gets/sets the value - /// - /// The getter returns the original value if the value hasn't been initialized. - public TValue Value { - get { -#if THREAD_SAFE - theLock?.EnterWriteLock(); try { -#endif - if (!isValueInitialized) { - value = readOriginalValue(); - readOriginalValue = null; - isValueInitialized = true; - } - return value; -#if THREAD_SAFE - } finally { theLock?.ExitWriteLock(); } -#endif - } - set { -#if THREAD_SAFE - theLock?.EnterWriteLock(); try { -#endif - this.value = value; - readOriginalValue = null; - isUserValue = true; - isValueInitialized = true; -#if THREAD_SAFE - } finally { theLock?.ExitWriteLock(); } -#endif - } - } - - /// - /// Returns true if the value has been initialized - /// - public bool IsValueInitialized { -#if THREAD_SAFE - get { - theLock?.EnterReadLock(); - try { - return isValueInitialized; - } - finally { theLock?.ExitReadLock(); } - } -#else - get => isValueInitialized; -#endif - } - - /// - /// Returns true if the value was set by the user - /// - public bool IsUserValue { -#if THREAD_SAFE - get { - theLock?.EnterReadLock(); - try { - return isUserValue; - } - finally { theLock?.ExitReadLock(); } - } -#else - get => isUserValue; -#endif - } - } -} diff --git a/Plugins/dnlib/W32Resources/ResourceData.cs b/Plugins/dnlib/W32Resources/ResourceData.cs deleted file mode 100644 index a2d3d3f..0000000 --- a/Plugins/dnlib/W32Resources/ResourceData.cs +++ /dev/null @@ -1,77 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using dnlib.IO; - -namespace dnlib.W32Resources { - /// - /// A resource blob - /// - public sealed class ResourceData : ResourceDirectoryEntry { - readonly DataReaderFactory dataReaderFactory; - readonly uint resourceStartOffset; - readonly uint resourceLength; - - uint codePage; - uint reserved; - - /// - /// Gets the data reader - /// - /// - public DataReader CreateReader() => dataReaderFactory.CreateReader(resourceStartOffset, resourceLength); - - /// - /// Gets/sets the code page - /// - public uint CodePage { - get => codePage; - set => codePage = value; - } - - /// - /// Gets/sets the reserved field - /// - public uint Reserved { - get => reserved; - set => reserved = value; - } - - /// - /// Constructor - /// - /// Name - public ResourceData(ResourceName name) - : this(name, ByteArrayDataReaderFactory.Create(Array2.Empty(), filename: null), 0, 0) { - } - - /// - /// Constructor - /// - /// Data reader factory - /// Offset of resource data - /// Length of resource data - /// Name - public ResourceData(ResourceName name, DataReaderFactory dataReaderFactory, uint offset, uint length) - : this(name, dataReaderFactory, offset, length, 0, 0) { - } - - /// - /// Constructor - /// - /// Data reader factory - /// Offset of resource data - /// Length of resource data - /// Name - /// Code page - /// Reserved value - public ResourceData(ResourceName name, DataReaderFactory dataReaderFactory, uint offset, uint length, uint codePage, uint reserved) - : base(name) { - this.dataReaderFactory = dataReaderFactory ?? throw new ArgumentNullException(nameof(dataReaderFactory)); - resourceStartOffset = offset; - resourceLength = length; - this.codePage = codePage; - this.reserved = reserved; - } - } -} diff --git a/Plugins/dnlib/W32Resources/ResourceDirectory.cs b/Plugins/dnlib/W32Resources/ResourceDirectory.cs deleted file mode 100644 index da802ba..0000000 --- a/Plugins/dnlib/W32Resources/ResourceDirectory.cs +++ /dev/null @@ -1,274 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Collections.Generic; -using dnlib.Utils; -using dnlib.IO; -using dnlib.PE; - -namespace dnlib.W32Resources { - /// - /// A Win32 resource directory (see IMAGE_RESOURCE_DIRECTORY in the Windows SDK) - /// - public abstract class ResourceDirectory : ResourceDirectoryEntry { - /// See - protected uint characteristics; - /// See - protected uint timeDateStamp; - /// See - protected ushort majorVersion; - /// See - protected ushort minorVersion; - /// See - private protected LazyList directories; - /// See - private protected LazyList data; - - /// - /// Gets/sets the characteristics - /// - public uint Characteristics { - get => characteristics; - set => characteristics = value; - } - - /// - /// Gets/sets the time date stamp - /// - public uint TimeDateStamp { - get => timeDateStamp; - set => timeDateStamp = value; - } - - /// - /// Gets/sets the major version number - /// - public ushort MajorVersion { - get => majorVersion; - set => majorVersion = value; - } - - /// - /// Gets/sets the minor version number - /// - public ushort MinorVersion { - get => minorVersion; - set => minorVersion = value; - } - - /// - /// Gets all directory entries - /// - public IList Directories => directories; - - /// - /// Gets all resource data - /// - public IList Data => data; - - /// - /// Constructor - /// - /// Name - protected ResourceDirectory(ResourceName name) - : base(name) { - } - - /// - /// Finds a by name - /// - /// Name - /// A or null if it wasn't found - public ResourceDirectory FindDirectory(ResourceName name) { - foreach (var dir in directories) { - if (dir.Name == name) - return dir; - } - return null; - } - - /// - /// Finds a by name - /// - /// Name - /// A or null if it wasn't found - public ResourceData FindData(ResourceName name) { - foreach (var d in data) { - if (d.Name == name) - return d; - } - return null; - } - } - - /// - /// A Win32 resource directory created by the user - /// - public class ResourceDirectoryUser : ResourceDirectory { - /// - /// Constructor - /// - /// Name - public ResourceDirectoryUser(ResourceName name) - : base(name) { - directories = new LazyList(); - data = new LazyList(); - } - } - - /// - /// A Win32 resource directory created from a PE file - /// - public sealed class ResourceDirectoryPE : ResourceDirectory { - /// - /// To make sure we don't get stuck in an infinite loop, don't allow more than this - /// many sub directories. - /// - const uint MAX_DIR_DEPTH = 10; - - /// Owner - readonly Win32ResourcesPE resources; - /// Directory depth. When creating more 's, - /// the instances get this value + 1 - uint depth; - - /// - /// Info about all 's we haven't created yet - /// - List dataInfos; - - /// - /// Info about all 's we haven't created yet - /// - List dirInfos; - - readonly struct EntryInfo { - public readonly ResourceName name; - - /// Offset of resource directory / data - public readonly uint offset; - - public EntryInfo(ResourceName name, uint offset) { - this.name = name; - this.offset = offset; - } - - public override string ToString() => $"{offset:X8} {name}"; - } - - /// - /// Constructor - /// - /// Starts from 0. If it's big enough, we'll stop reading more data. - /// Name - /// Resources - /// Reader positioned at the start of this resource directory - public ResourceDirectoryPE(uint depth, ResourceName name, Win32ResourcesPE resources, ref DataReader reader) - : base(name) { - this.resources = resources; - this.depth = depth; - Initialize(ref reader); - } - - /// - /// Reads the directory header and initializes and - /// . - /// - /// - void Initialize(ref DataReader reader) { - if (depth > MAX_DIR_DEPTH || !reader.CanRead(16U)) { - InitializeDefault(); - return; - } - - characteristics = reader.ReadUInt32(); - timeDateStamp = reader.ReadUInt32(); - majorVersion = reader.ReadUInt16(); - minorVersion = reader.ReadUInt16(); - ushort numNamed = reader.ReadUInt16(); - ushort numIds = reader.ReadUInt16(); - - int total = numNamed + numIds; - if (!reader.CanRead((uint)total * 8)) { - InitializeDefault(); - return; - } - - dataInfos = new List(); - dirInfos = new List(); - uint offset = reader.Position; - for (int i = 0; i < total; i++, offset += 8) { - reader.Position = offset; - uint nameOrId = reader.ReadUInt32(); - uint dataOrDirectory = reader.ReadUInt32(); - ResourceName name; - if ((nameOrId & 0x80000000) != 0) - name = new ResourceName(ReadString(ref reader, nameOrId & 0x7FFFFFFF) ?? string.Empty); - else - name = new ResourceName((int)nameOrId); - - if ((dataOrDirectory & 0x80000000) == 0) - dataInfos.Add(new EntryInfo(name, dataOrDirectory)); - else - dirInfos.Add(new EntryInfo(name, dataOrDirectory & 0x7FFFFFFF)); - } - - directories = new LazyList(dirInfos.Count, null, (ctx, i) => ReadResourceDirectory(i)); - data = new LazyList(dataInfos.Count, null, (ctx, i) => ReadResourceData(i)); - } - - /// - /// Reads a string - /// - /// Reader - /// Offset of string - /// The string or null if we could not read it - static string ReadString(ref DataReader reader, uint offset) { - reader.Position = offset; - if (!reader.CanRead(2U)) - return null; - int size = reader.ReadUInt16(); - int sizeInBytes = size * 2; - if (!reader.CanRead((uint)sizeInBytes)) - return null; - try { - return reader.ReadUtf16String(sizeInBytes / 2); - } - catch { - return null; - } - } - - ResourceDirectory ReadResourceDirectory(int i) { - var info = dirInfos[i]; - var reader = resources.GetResourceReader(); - reader.Position = Math.Min(reader.Length, info.offset); - return new ResourceDirectoryPE(depth + 1, info.name, resources, ref reader); - } - - ResourceData ReadResourceData(int i) { - var info = dataInfos[i]; - var reader = resources.GetResourceReader(); - reader.Position = Math.Min(reader.Length, info.offset); - - ResourceData data; - if (reader.CanRead(16U)) { - var rva = (RVA)reader.ReadUInt32(); - uint size = reader.ReadUInt32(); - uint codePage = reader.ReadUInt32(); - uint reserved = reader.ReadUInt32(); - resources.GetDataReaderInfo(rva, size, out var dataReaderFactory, out uint dataOffset, out uint dataLength); - data = new ResourceData(info.name, dataReaderFactory, dataOffset, dataLength, codePage, reserved); - } - else - data = new ResourceData(info.name); - - return data; - } - - void InitializeDefault() { - directories = new LazyList(); - data = new LazyList(); - } - } -} diff --git a/Plugins/dnlib/W32Resources/ResourceDirectoryEntry.cs b/Plugins/dnlib/W32Resources/ResourceDirectoryEntry.cs deleted file mode 100644 index b4ddaac..0000000 --- a/Plugins/dnlib/W32Resources/ResourceDirectoryEntry.cs +++ /dev/null @@ -1,27 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -namespace dnlib.W32Resources { - /// - /// Base class of and - /// - public abstract class ResourceDirectoryEntry { - ResourceName name; - - /// - /// Gets/sets the name - /// - public ResourceName Name { - get => name; - set => name = value; - } - - /// - /// Constructor - /// - /// Name - protected ResourceDirectoryEntry(ResourceName name) => this.name = name; - - /// - public override string ToString() => name.ToString(); - } -} diff --git a/Plugins/dnlib/W32Resources/ResourceName.cs b/Plugins/dnlib/W32Resources/ResourceName.cs deleted file mode 100644 index d5f36dd..0000000 --- a/Plugins/dnlib/W32Resources/ResourceName.cs +++ /dev/null @@ -1,107 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; - -namespace dnlib.W32Resources { - /// - /// A Win32 resource name. It can be either an integer or a string. - /// - public readonly struct ResourceName : IComparable, IEquatable { - readonly int id; - readonly string name; - - /// - /// true if is valid - /// - public bool HasId => name is null; - - /// - /// true if is valid - /// - public bool HasName => name is not null; - - /// - /// The ID. It's only valid if is true - /// - public int Id => id; - - /// - /// The name. It's only valid if is true - /// - public string Name => name; - - /// - /// Constructor - /// - /// ID - public ResourceName(int id) { - this.id = id; - name = null; - } - - /// - /// Constructor - /// - /// Name - public ResourceName(string name) { - id = 0; - this.name = name; - } - - /// Converts input to a - public static implicit operator ResourceName(int id) => new ResourceName(id); - - /// Converts input to a - public static implicit operator ResourceName(string name) => new ResourceName(name); - - /// Overloaded operator - public static bool operator <(ResourceName left, ResourceName right) => left.CompareTo(right) < 0; - - /// Overloaded operator - public static bool operator <=(ResourceName left, ResourceName right) => left.CompareTo(right) <= 0; - - /// Overloaded operator - public static bool operator >(ResourceName left, ResourceName right) => left.CompareTo(right) > 0; - - /// Overloaded operator - public static bool operator >=(ResourceName left, ResourceName right) => left.CompareTo(right) >= 0; - - /// Overloaded operator - public static bool operator ==(ResourceName left, ResourceName right) => left.Equals(right); - - /// Overloaded operator - public static bool operator !=(ResourceName left, ResourceName right) => !left.Equals(right); - - /// - public int CompareTo(ResourceName other) { - if (HasId != other.HasId) { - // Sort names before ids - return HasName ? -1 : 1; - } - if (HasId) - return id.CompareTo(other.id); - else - return name.ToUpperInvariant().CompareTo(other.name.ToUpperInvariant()); - } - - /// - public bool Equals(ResourceName other) => CompareTo(other) == 0; - - /// - public override bool Equals(object obj) { - if (!(obj is ResourceName)) - return false; - return Equals((ResourceName)obj); - } - - /// - public override int GetHashCode() { - if (HasId) - return id; - return name.GetHashCode(); - } - - /// - public override string ToString() => HasId ? id.ToString() : name; - } -} diff --git a/Plugins/dnlib/W32Resources/Win32Resources.cs b/Plugins/dnlib/W32Resources/Win32Resources.cs deleted file mode 100644 index d02f8a4..0000000 --- a/Plugins/dnlib/W32Resources/Win32Resources.cs +++ /dev/null @@ -1,266 +0,0 @@ -// dnlib: See LICENSE.txt for more info - -using System; -using System.Threading; -using dnlib.Utils; -using dnlib.IO; -using dnlib.PE; -using dnlib.Threading; - -namespace dnlib.W32Resources { - /// - /// Win32 resources base class - /// - public abstract class Win32Resources : IDisposable { - /// - /// Gets/sets the root directory - /// - public abstract ResourceDirectory Root { get; set; } - - /// - /// Finds a - /// - /// Type - /// The or null if none found - public ResourceDirectory Find(ResourceName type) { - var dir = Root; - if (dir is null) - return null; - return dir.FindDirectory(type); - } - - /// - /// Finds a - /// - /// Type - /// Name - /// The or null if none found - public ResourceDirectory Find(ResourceName type, ResourceName name) { - var dir = Find(type); - if (dir is null) - return null; - return dir.FindDirectory(name); - } - - /// - /// Finds a - /// - /// Type - /// Name - /// Language ID - /// The or null if none found - public ResourceData Find(ResourceName type, ResourceName name, ResourceName langId) { - var dir = Find(type, name); - if (dir is null) - return null; - return dir.FindData(langId); - } - - /// - public void Dispose() { - Dispose(true); - GC.SuppressFinalize(this); - } - - /// - /// Dispose method - /// - /// true if called by - protected virtual void Dispose(bool disposing) { - if (!disposing) - return; - Root = null; // Property handler will call Dispose() - } - } - - /// - /// Win32 resources class created by the user - /// - public class Win32ResourcesUser : Win32Resources { - ResourceDirectory root = new ResourceDirectoryUser(new ResourceName("root")); - - /// - public override ResourceDirectory Root { - get => root; - set => Interlocked.Exchange(ref root, value); - } - } - - /// - /// Win32 resources class created from a PE file - /// - public sealed class Win32ResourcesPE : Win32Resources { - /// - /// Converts data RVAs to file offsets in - /// - readonly IRvaFileOffsetConverter rvaConverter; - - /// - /// This reader only reads the raw data. The data RVA is found in the data header and - /// it's first converted to a file offset using . This file - /// offset is where we'll read from using this reader. - /// - DataReaderFactory dataReader_factory; - uint dataReader_offset; - uint dataReader_length; - bool owns_dataReader_factory; - - /// - /// This reader only reads the directory entries and data headers. The data is read - /// by - /// - DataReaderFactory rsrcReader_factory; - uint rsrcReader_offset; - uint rsrcReader_length; - bool owns_rsrcReader_factory; - - UserValue root; - -#if THREAD_SAFE - readonly Lock theLock = Lock.Create(); -#endif - - /// - public override ResourceDirectory Root { - get => root.Value; - set { - if (root.IsValueInitialized) { - var origValue = root.Value; - if (origValue == value) - return; - } - root.Value = value; - } - } - - /// - /// Gets the resource reader - /// - internal DataReader GetResourceReader() => rsrcReader_factory.CreateReader(rsrcReader_offset, rsrcReader_length); - - /// - /// Constructor - /// - /// / converter - /// Reader for the whole Win32 resources section (usually - /// the .rsrc section). It's used to read 's and - /// 's but not the actual data blob. - /// Offset of resource section - /// Length of resource section - /// true if this instance can dispose of - /// Data reader (it's used after converting an - /// to a ) - /// Offset of resource section - /// Length of resource section - /// true if this instance can dispose of - public Win32ResourcesPE(IRvaFileOffsetConverter rvaConverter, DataReaderFactory rsrcReader_factory, uint rsrcReader_offset, uint rsrcReader_length, bool owns_rsrcReader_factory, DataReaderFactory dataReader_factory, uint dataReader_offset, uint dataReader_length, bool owns_dataReader_factory) { - this.rvaConverter = rvaConverter ?? throw new ArgumentNullException(nameof(rvaConverter)); - this.rsrcReader_factory = rsrcReader_factory ?? throw new ArgumentNullException(nameof(rsrcReader_factory)); - this.rsrcReader_offset = rsrcReader_offset; - this.rsrcReader_length = rsrcReader_length; - this.owns_rsrcReader_factory = owns_rsrcReader_factory; - this.dataReader_factory = dataReader_factory ?? throw new ArgumentNullException(nameof(dataReader_factory)); - this.dataReader_offset = dataReader_offset; - this.dataReader_length = dataReader_length; - this.owns_dataReader_factory = owns_dataReader_factory; - Initialize(); - } - - /// - /// Constructor - /// - /// The PE image - public Win32ResourcesPE(IPEImage peImage) - : this(peImage, null, 0, 0, false) { - } - - /// - /// Constructor - /// - /// The PE image - /// Reader for the whole Win32 resources section (usually - /// the .rsrc section) or null if we should create one from the resource data - /// directory in the optional header - /// Offset of resource section - /// Length of resource section - /// true if this instance can dispose of - public Win32ResourcesPE(IPEImage peImage, DataReaderFactory rsrcReader_factory, uint rsrcReader_offset, uint rsrcReader_length, bool owns_rsrcReader_factory) { - rvaConverter = peImage ?? throw new ArgumentNullException(nameof(peImage)); - dataReader_factory = peImage.DataReaderFactory; - dataReader_offset = 0; - dataReader_length = dataReader_factory.Length; - if (rsrcReader_factory is not null) { - this.rsrcReader_factory = rsrcReader_factory; - this.rsrcReader_offset = rsrcReader_offset; - this.rsrcReader_length = rsrcReader_length; - this.owns_rsrcReader_factory = owns_rsrcReader_factory; - } - else { - var dataDir = peImage.ImageNTHeaders.OptionalHeader.DataDirectories[2]; - if (dataDir.VirtualAddress != 0 && dataDir.Size != 0) { - var reader = peImage.CreateReader(dataDir.VirtualAddress, dataDir.Size); - this.rsrcReader_factory = peImage.DataReaderFactory; - this.rsrcReader_offset = reader.StartOffset; - this.rsrcReader_length = reader.Length; - } - else { - this.rsrcReader_factory = ByteArrayDataReaderFactory.Create(Array2.Empty(), filename: null); - this.rsrcReader_offset = 0; - this.rsrcReader_length = 0; - } - } - Initialize(); - } - - void Initialize() { - root.ReadOriginalValue = () => { - var rsrcReader_factory = this.rsrcReader_factory; - 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); - }; -#if THREAD_SAFE - root.Lock = theLock; -#endif - } - - /// - /// Creates a new data reader - /// - /// RVA of data - /// Size of data - /// - public DataReader CreateReader(RVA rva, uint size) { - GetDataReaderInfo(rva, size, out var dataReaderFactory, out uint dataOffset, out uint dataLength); - return dataReaderFactory.CreateReader(dataOffset, dataLength); - } - - internal void GetDataReaderInfo(RVA rva, uint size, out DataReaderFactory dataReaderFactory, out uint dataOffset, out uint dataLength) { - dataOffset = (uint)rvaConverter.ToFileOffset(rva); - if ((ulong)dataOffset + size <= dataReader_factory.Length) { - dataReaderFactory = dataReader_factory; - dataLength = size; - return; - } - else { - dataReaderFactory = ByteArrayDataReaderFactory.Create(Array2.Empty(), filename: null); - dataOffset = 0; - dataLength = 0; - } - } - - /// - protected override void Dispose(bool disposing) { - if (!disposing) - return; - if (owns_dataReader_factory) - dataReader_factory?.Dispose(); - if (owns_rsrcReader_factory) - rsrcReader_factory?.Dispose(); - dataReader_factory = null; - rsrcReader_factory = null; - base.Dispose(disposing); - } - } -} diff --git a/Plugins/dnlib/dnlib.asmdef b/Plugins/dnlib/dnlib.asmdef deleted file mode 100644 index 0ba4b8f..0000000 --- a/Plugins/dnlib/dnlib.asmdef +++ /dev/null @@ -1,16 +0,0 @@ -{ - "name": "dnlib", - "rootNamespace": "", - "references": [], - "includePlatforms": [ - "Editor" - ], - "excludePlatforms": [], - "allowUnsafeCode": true, - "overrideReferences": false, - "precompiledReferences": [], - "autoReferenced": true, - "defineConstraints": [], - "versionDefines": [], - "noEngineReferences": false -} \ No newline at end of file