public static MethodImportAttributes MakeFlags(CallingConvention callingConvention)
        {
            MethodImportAttributes result = 0;

            switch (callingConvention)
            {
            default:                     // Dev10: uses default without reporting an error
                result |= MethodImportAttributes.CallingConventionStdCall;
                break;

            case CallingConvention.C:
                result |= MethodImportAttributes.CallingConventionCDecl;
                break;

            case CallingConvention.Standard:
                result |= MethodImportAttributes.CallingConventionStdCall;
                break;

            case CallingConvention.ThisCall:
                result |= MethodImportAttributes.CallingConventionThisCall;
                break;

            case CallingConvention.FastCall:
                result |= MethodImportAttributes.CallingConventionFastCall;
                break;
            }
            return(result);
        }
 // used by DllImportAttribute
 public void SetDllImport(int attributeIndex, string moduleName, string entryPointName, MethodImportAttributes flags, bool preserveSig)
 {
     VerifySealed(expected: false);
     Debug.Assert(attributeIndex >= 0);
     _platformInvokeInfo = new DllImportData(moduleName, entryPointName, flags);
     _dllImportIndex = attributeIndex;
     _dllImportPreserveSig = preserveSig;
     SetDataStored();
 }
Esempio n. 3
0
 internal DllImportData(
     string?moduleName,
     string?entryPointName,
     MethodImportAttributes flags
     )
 {
     _moduleName     = moduleName;
     _entryPointName = entryPointName;
     _flags          = flags;
 }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 public void SetDllImport(
     int attributeIndex,
     string moduleName,
     string entryPointName,
     MethodImportAttributes flags,
     bool preserveSig
     )
 {
     VerifySealed(expected: false);
     Debug.Assert(attributeIndex >= 0);
     _platformInvokeInfo   = new DllImportData(moduleName, entryPointName, flags);
     _dllImportIndex       = attributeIndex;
     _dllImportPreserveSig = preserveSig;
     SetDataStored();
 }
 public DecodedMethodImportAttributes(MethodImportAttributes attrs)
 {
     this.exact_spelling = (attrs & MethodImportAttributes.ExactSpelling) != 0;
     {
         MethodImportAttributes char_set_attr = attrs & MethodImportAttributes.CharSetMask;
         this.char_set = char_set_attr switch
         {
             MethodImportAttributes.None => CharSet.none,
             MethodImportAttributes.CharSetAnsi => CharSet.ansi,
             MethodImportAttributes.CharSetUnicode => CharSet.unicode,
             MethodImportAttributes.CharSetAuto => CharSet.auto,
             _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes char_set {0}", char_set_attr)),
         };
     }
     {
         MethodImportAttributes best_fit_attr = attrs & MethodImportAttributes.BestFitMappingMask;
         this.best_fit = best_fit_attr switch
         {
             MethodImportAttributes.None => null,
             MethodImportAttributes.BestFitMappingDisable => false,
             MethodImportAttributes.BestFitMappingEnable => true,
             _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes best_fit {0}", best_fit_attr)),
         };
     }
     this.set_last_error = (attrs & MethodImportAttributes.SetLastError) != 0;
     {
         MethodImportAttributes call_conv_attr = attrs & MethodImportAttributes.CallingConventionMask;
         this.call_conv = call_conv_attr switch
         {
             MethodImportAttributes.CallingConventionWinApi => CallConv.winapi,
             MethodImportAttributes.CallingConventionCDecl => CallConv.cdecl,
             MethodImportAttributes.CallingConventionStdCall => CallConv.stdcall,
             MethodImportAttributes.CallingConventionThisCall => CallConv.thiscall,
             MethodImportAttributes.CallingConventionFastCall => CallConv.fastcall,
             _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes call_conv {0}", call_conv_attr)),
         };
     }
     {
         MethodImportAttributes throw_attr = attrs & MethodImportAttributes.ThrowOnUnmappableCharMask;
         this.throw_on_unmappable_char = throw_attr switch
         {
             MethodImportAttributes.None => null,
             MethodImportAttributes.ThrowOnUnmappableCharDisable => false,
             MethodImportAttributes.ThrowOnUnmappableCharEnable => true,
             _ => throw new InvalidDataException(string.Format("unknown MethodImportAttributes throw_on_unmappable {0}", throw_attr)),
         };
     }
 }
Esempio n. 7
0
        private void ProcessPInvokeMapData(
            MethodInfo method,
            out string libraryName,
            out string entryName,
            out MethodImportAttributes implAttr)
        {
            CustomAttributeData dllImportData = null;

            foreach (var custAttr in method.GetCustomAttributesData())
            {
                if (custAttr.AttributeType == typeof(DllImportAttribute))
                {
                    dllImportData = custAttr;
                    break;
                }
            }

            if (dllImportData == null)
            {
                throw new InvalidProgramException($"Missing P/Invoke map data for: {method.Name}");
            }

            // Initialize the outputs
            libraryName = (string)dllImportData.ConstructorArguments[0].Value;
            entryName   = method.Name;
            implAttr    = MethodImportAttributes.CallingConventionWinApi;

            foreach (var nargs in dllImportData.NamedArguments)
            {
                object argValue = nargs.TypedValue.Value;
                switch (nargs.MemberName)
                {
                case nameof(DllImportAttribute.BestFitMapping):
                    implAttr |= ((bool)argValue)
                                ? MethodImportAttributes.BestFitMappingEnable
                                : MethodImportAttributes.BestFitMappingDisable;
                    break;

                case nameof(DllImportAttribute.CallingConvention):
                    // Clear previous value.
                    implAttr &= ~MethodImportAttributes.CallingConventionMask;

                    implAttr |= (CallingConvention)argValue switch
                    {
                        CallingConvention.Winapi => MethodImportAttributes.CallingConventionWinApi,
                        CallingConvention.Cdecl => MethodImportAttributes.CallingConventionCDecl,
                        CallingConvention.StdCall => MethodImportAttributes.CallingConventionStdCall,
                        CallingConvention.ThisCall => MethodImportAttributes.CallingConventionThisCall,
                        CallingConvention.FastCall => MethodImportAttributes.CallingConventionFastCall,
                        _ => MethodImportAttributes.CallingConventionWinApi,
                    };
                    break;

                case nameof(DllImportAttribute.CharSet):
                    // Clear previous value.
                    implAttr &= ~MethodImportAttributes.CharSetMask;

                    implAttr |= (CharSet)argValue switch
                    {
                        CharSet.Ansi => MethodImportAttributes.CharSetAnsi,
                        CharSet.Unicode => MethodImportAttributes.CharSetUnicode,
                        CharSet.Auto => MethodImportAttributes.CharSetAuto,
                        _ => MethodImportAttributes.None,
                    };
                    break;

                case nameof(DllImportAttribute.EntryPoint):
                    entryName = (string)argValue;
                    break;

                case nameof(DllImportAttribute.ExactSpelling):
                    implAttr |= ((bool)argValue)
                                ? MethodImportAttributes.ExactSpelling
                                : MethodImportAttributes.None;
                    break;

                case nameof(DllImportAttribute.SetLastError):
                    implAttr |= ((bool)argValue)
                                ? MethodImportAttributes.SetLastError
                                : MethodImportAttributes.None;
                    break;

                case nameof(DllImportAttribute.ThrowOnUnmappableChar):
                    implAttr |= ((bool)argValue)
                                ? MethodImportAttributes.ThrowOnUnmappableCharEnable
                                : MethodImportAttributes.ThrowOnUnmappableCharDisable;
                    break;
                }
            }
        }
Esempio n. 8
0
        internal static MethodImportAttributes MakeFlags(bool exactSpelling, CharSet charSet, bool setLastError, CallingConvention callingConvention, bool?useBestFit, bool?throwOnUnmappable)
        {
            MethodImportAttributes result = 0;

            if (exactSpelling)
            {
                result |= MethodImportAttributes.ExactSpelling;
            }

            switch (charSet)
            {
            case CharSet.Ansi:
                result |= MethodImportAttributes.CharSetAnsi;
                break;

            case CharSet.Unicode:
                result |= MethodImportAttributes.CharSetUnicode;
                break;

            case Cci.Constants.CharSet_Auto:
                result |= MethodImportAttributes.CharSetAuto;
                break;

                // Dev10: use default without reporting an error
            }

            if (setLastError)
            {
                result |= MethodImportAttributes.SetLastError;
            }

            switch (callingConvention)
            {
            default:     // Dev10: uses default without reporting an error
                result |= MethodImportAttributes.CallingConventionWinApi;
                break;

            case CallingConvention.Cdecl:
                result |= MethodImportAttributes.CallingConventionCDecl;
                break;

            case CallingConvention.StdCall:
                result |= MethodImportAttributes.CallingConventionStdCall;
                break;

            case CallingConvention.ThisCall:
                result |= MethodImportAttributes.CallingConventionThisCall;
                break;

            case Cci.Constants.CallingConvention_FastCall:
                result |= MethodImportAttributes.CallingConventionFastCall;
                break;
            }

            if (throwOnUnmappable.HasValue)
            {
                if (throwOnUnmappable.Value)
                {
                    result |= MethodImportAttributes.ThrowOnUnmappableCharEnable;
                }
                else
                {
                    result |= MethodImportAttributes.ThrowOnUnmappableCharDisable;
                }
            }

            if (useBestFit.HasValue)
            {
                if (useBestFit.Value)
                {
                    result |= MethodImportAttributes.BestFitMappingEnable;
                }
                else
                {
                    result |= MethodImportAttributes.BestFitMappingDisable;
                }
            }

            return(result);
        }
Esempio n. 9
0
 public void AddMethodImport(
     EntityHandle member,
     MethodImportAttributes attributes, 
     StringHandle name, 
     ModuleReferenceHandle module)
 {
     _implMapTable.Add(new ImplMapRow
     {
         MemberForwarded = (uint)CodedIndex.ToMemberForwarded(member),
         ImportName = name,
         ImportScope = (uint)MetadataTokens.GetRowNumber(module),
         MappingFlags = (ushort)attributes,
     });
 }
Esempio n. 10
0
 internal MethodImport(MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module)
 {
     _attributes = attributes;
     _name = name;
     _module = module;
 }
Esempio n. 11
0
 public DllImportData(string moduleName, string entryPointName, MethodImportAttributes flags)
 {
     _moduleName     = moduleName;
     _entryPointName = entryPointName;
     _flags          = flags;
 }
Esempio n. 12
0
 internal MethodImport(MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module)
 {
     _attributes = attributes;
     _name       = name;
     _module     = module;
 }
Esempio n. 13
0
 internal MethodImport(MethodImportAttributes attributes, StringHandle name, ModuleReferenceHandle module)
 {
     this.attributes = attributes;
     this.name = name;
     this.module = module;
 }
Esempio n. 14
0
 public void AddMethodImport(
     uint member,
     MethodImportAttributes attributes, 
     StringIdx name, 
     int moduleReferenceRowId)
 {
     _implMapTable.Add(new ImplMapRow
     {
         MemberForwarded = member,
         ImportName = name,
         ImportScope = (uint)moduleReferenceRowId,
         MappingFlags = (ushort)attributes,
     });
 }
Esempio n. 15
0
 internal DllImportData(string moduleName, string entryPointName, MethodImportAttributes flags)
 {
     _moduleName = moduleName;
     _entryPointName = entryPointName;
     _flags = flags;
 }
Esempio n. 16
0
        public override PInvokeMetadata GetPInvokeMethodMetadata()
        {
            if (!IsPInvoke)
            {
                return(default(PInvokeMetadata));
            }

            MetadataReader   metadataReader = MetadataReader;
            MethodDefinition methodDef      = metadataReader.GetMethodDefinition(_handle);
            MethodImport     import         = methodDef.GetImport();
            string           name           = metadataReader.GetString(import.Name);

            ModuleReference moduleRef  = metadataReader.GetModuleReference(import.Module);
            string          moduleName = metadataReader.GetString(moduleRef.Name);

            MethodImportAttributes importAttributes = import.Attributes;

            // If either BestFitMapping or ThrowOnUnmappable wasn't set on the p/invoke,
            // look for the value in the owning type or assembly.
            if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 ||
                (importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
            {
                TypeDefinition declaringType = metadataReader.GetTypeDefinition(methodDef.GetDeclaringType());

                // Start with owning type
                MethodImportAttributes fromCA = GetImportAttributesFromBestFitMappingAttribute(declaringType.GetCustomAttributes());
                if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0)
                {
                    importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask;
                }
                if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
                {
                    importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask;
                }

                // If we still don't know, check the assembly
                if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0 ||
                    (importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
                {
                    fromCA = GetImportAttributesFromBestFitMappingAttribute(metadataReader.GetAssemblyDefinition().GetCustomAttributes());
                    if ((importAttributes & MethodImportAttributes.BestFitMappingMask) == 0)
                    {
                        importAttributes |= fromCA & MethodImportAttributes.BestFitMappingMask;
                    }
                    if ((importAttributes & MethodImportAttributes.ThrowOnUnmappableCharMask) == 0)
                    {
                        importAttributes |= fromCA & MethodImportAttributes.ThrowOnUnmappableCharMask;
                    }
                }
            }

            // Spot check the enums match
            Debug.Assert((int)MethodImportAttributes.CallingConventionStdCall == (int)PInvokeAttributes.CallingConventionStdCall);
            Debug.Assert((int)MethodImportAttributes.CharSetAuto == (int)PInvokeAttributes.CharSetAuto);
            Debug.Assert((int)MethodImportAttributes.CharSetUnicode == (int)PInvokeAttributes.CharSetUnicode);
            Debug.Assert((int)MethodImportAttributes.SetLastError == (int)PInvokeAttributes.SetLastError);

            PInvokeAttributes attributes = (PInvokeAttributes)importAttributes;

            if ((ImplAttributes & MethodImplAttributes.PreserveSig) != 0)
            {
                attributes |= PInvokeAttributes.PreserveSig;
            }

            return(new PInvokeMetadata(moduleName, name, attributes));
        }