/// <summary> /// Determines whether the assembly was compiled without optimizations using the DebuggableAttribute /// </summary> public static bool HasOptimizationsDisabled(this EcmaAssembly assembly) { bool result = false; MetadataReader reader = assembly.MetadataReader; var attributeHandles = assembly.AssemblyDefinition.GetCustomAttributes(); CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle(attributeHandles, "System.Diagnostics", "DebuggableAttribute"); if (!attributeHandle.IsNil) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decoded = attribute.DecodeValue(new CustomAttributeTypeProvider(assembly)); if (decoded.FixedArguments.Length == 1) { // DebuggableAttribute( DebuggableAttribute.DebuggingModes modes ) if (!(decoded.FixedArguments[0].Value is int)) { ThrowHelper.ThrowBadImageFormatException(); } DebuggableAttribute.DebuggingModes modes = (DebuggableAttribute.DebuggingModes)decoded.FixedArguments[0].Value; result = modes.HasFlag(DebuggableAttribute.DebuggingModes.DisableOptimizations) && modes.HasFlag(DebuggableAttribute.DebuggingModes.Default); } else if (decoded.FixedArguments.Length == 2) { // DebuggableAttribute( bool isJITTrackingEnabled, bool isJITOptimizerDisabled ) if (!(decoded.FixedArguments[0].Value is bool) || !(decoded.FixedArguments[1].Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } result = ((bool)decoded.FixedArguments[1].Value); } } return(result); }
/// <summary> /// Returns the TargetFrameworkIdentifier of an assembly, or null if not found /// </summary> public static string GetTargetFrameworkIdentifier(this AssemblyDefinition assembly, MetadataReader reader) { foreach (var handle in assembly.GetCustomAttributes()) { var attribute = reader.GetCustomAttribute(handle); var name = reader.GetCustomAttributeFullName(attribute); if (name == "System.Runtime.Versioning.TargetFrameworkAttribute") { var arguments = attribute.GetCustomAttributeArguments(); foreach (var p in arguments.FixedArguments) { // Of the form "MonoAndroid,Version=v8.1" var value = p.Value?.ToString(); if (!string.IsNullOrEmpty(value)) { int commaIndex = value.IndexOf(",", StringComparison.Ordinal); if (commaIndex != -1) { return(value.Substring(0, commaIndex)); } } } return(null); } } return(null); }
private MethodImportAttributes GetImportAttributesFromBestFitMappingAttribute(CustomAttributeHandleCollection attributeHandles) { // Look for the [BestFitMapping(BestFitMapping: x, ThrowOnUnmappableChar = y)] attribute and // translate that to MethodImportAttributes MethodImportAttributes result = 0; MetadataReader reader = MetadataReader; CustomAttributeHandle attributeHandle = reader.GetCustomAttributeHandle( attributeHandles, "System.Runtime.InteropServices", "BestFitMappingAttribute"); if (!attributeHandle.IsNil) { CustomAttribute attribute = reader.GetCustomAttribute(attributeHandle); CustomAttributeValue <TypeDesc> decoded = attribute.DecodeValue( new CustomAttributeTypeProvider(_type.EcmaModule)); if (decoded.FixedArguments.Length != 1 || !(decoded.FixedArguments[0].Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)decoded.FixedArguments[0].Value) { result |= MethodImportAttributes.BestFitMappingEnable; } else { result |= MethodImportAttributes.BestFitMappingDisable; } foreach (CustomAttributeNamedArgument <TypeDesc> namedArg in decoded.NamedArguments) { if (namedArg.Name == "ThrowOnUnmappableChar") { if (!(namedArg.Value is bool)) { ThrowHelper.ThrowBadImageFormatException(); } if ((bool)namedArg.Value) { result |= MethodImportAttributes.ThrowOnUnmappableCharEnable; } else { result |= MethodImportAttributes.ThrowOnUnmappableCharDisable; } break; } } } return(result); }