예제 #1
0
        private static bool LoadLibrary(string type, string member,
                                        string library, string symbol, AssemblyCheckInfo report, out string error)
        {
            error = null;
            IntPtr h = g_module_open(library,
                                     G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);

            try {
                Trace.WriteLine("    Trying library name: " + library);
                if (h != IntPtr.Zero)
                {
                    string soname = Marshal.PtrToStringAnsi(g_module_name(h));
                    Trace.WriteLine("Able to load library " + library +
                                    "; soname=" + soname);
                    IntPtr ignore;
                    if (g_module_symbol(h, symbol, out ignore) == 0)
                    {
                        report.Errors.Add(new MessageInfo(
                                              type, member,
                                              string.Format("library `{0}' is missing symbol `{1}'",
                                                            library, symbol)));
                    }
                    return(true);
                }
                error = Marshal.PtrToStringAnsi(g_module_error());
                Trace.WriteLine("\tError loading library `" + library + "': " + error);
            }
            finally {
                if (h != IntPtr.Zero)
                {
                    g_module_close(h);
                }
            }
            return(false);
        }
예제 #2
0
 private void Check(Assembly a, AssemblyCheckInfo report)
 {
     foreach (Type t in a.GetTypes())
     {
         Check(t, report);
     }
 }
예제 #3
0
        public void CheckWithPartialName(string partial, AssemblyCheckInfo report)
        {
            string   p = partial;
            Assembly a;
            bool     retry;

            do
            {
                a     = Assembly.LoadWithPartialName(p);
                retry = p.EndsWith(".dll");
                if (retry)
                {
                    p = p.Substring(0, p.Length - 4);
                }
            } while (a == null && retry);

            if (a == null)
            {
                report.Errors.Add(new MessageInfo(null, null,
                                                  "Could not load assembly reference `" + partial + "'."));
                return;
            }

            Check(a, report);
        }
예제 #4
0
        private void CheckMember(Type type, MemberInfo mi, AssemblyCheckInfo report)
        {
            DllImportAttribute[] attributes = null;
            MethodBase[]         methods    = null;
            switch (mi.MemberType)
            {
            case MemberTypes.Constructor:
            case MemberTypes.Method: {
                MethodBase mb = (MethodBase)mi;
                attributes = new DllImportAttribute[] { GetDllImportInfo(mb) };
                methods    = new MethodBase[] { mb };
                break;
            }

            case MemberTypes.Event: {
                EventInfo  ei     = (EventInfo)mi;
                MethodBase add    = ei.GetAddMethod(true);
                MethodBase remove = ei.GetRemoveMethod(true);
                attributes = new DllImportAttribute[] {
                    GetDllImportInfo(add), GetDllImportInfo(remove)
                };
                methods = new MethodBase[] { add, remove };
                break;
            }

            case MemberTypes.Property: {
                PropertyInfo pi        = (PropertyInfo)mi;
                MethodInfo[] accessors = pi.GetAccessors(true);
                if (accessors == null)
                {
                    break;
                }
                attributes = new DllImportAttribute[accessors.Length];
                methods    = new MethodBase [accessors.Length];
                for (int i = 0; i < accessors.Length; ++i)
                {
                    attributes [i] = GetDllImportInfo(accessors [i]);
                    methods [i]    = accessors [i];
                }
                break;
            }
            }
            if (attributes == null || methods == null)
            {
                return;
            }

            for (int i = 0; i < attributes.Length; ++i)
            {
                if (attributes [i] == null)
                {
                    continue;
                }
                CheckLibrary(methods [i], attributes [i], report);
            }
        }
예제 #5
0
        private void Check(Type type, AssemblyCheckInfo report)
        {
            BindingFlags bf = BindingFlags.Instance | BindingFlags.Static |
                              BindingFlags.Public | BindingFlags.NonPublic;

            foreach (MemberInfo mi in type.GetMembers(bf))
            {
                CheckMember(type, mi, report);
            }
        }
예제 #6
0
 public void CheckFile(string file, AssemblyCheckInfo report)
 {
     try {
         Check(Assembly.LoadFile(file), report);
     }
     catch (FileNotFoundException e) {
         report.Errors.Add(new MessageInfo(null, null,
                                           "Could not load `" + file + "': " + e.Message));
     }
 }
예제 #7
0
        private static string[] GetLibraryNames(Type type, string library, AssemblyCheckInfo report)
        {
            // TODO: keep in sync with
            // mono/metadata/loader.c:mono_lookup_pinvoke_call
            ArrayList names = new ArrayList();

            string dll_map = report.GetDllmapEntry(type.Assembly.Location, library);

            if (dll_map != null)
            {
                names.Add(dll_map);
            }

            names.Add(library);
            int _dll_index = library.LastIndexOf(".dll");

            if (_dll_index >= 0)
            {
                names.Add(library.Substring(0, _dll_index));
            }

            if (!library.StartsWith("lib"))
            {
                names.Add("lib" + library);
            }

            IntPtr s = g_module_build_path(null, library);

            if (s != IntPtr.Zero)
            {
                try {
                    names.Add(Marshal.PtrToStringAnsi(s));
                }
                finally {
                    g_free(s);
                }
            }

            s = g_module_build_path(".", library);
            if (s != IntPtr.Zero)
            {
                try {
                    names.Add(Marshal.PtrToStringAnsi(s));
                }
                finally {
                    g_free(s);
                }
            }

            return((string[])names.ToArray(typeof(string)));
        }
예제 #8
0
        public static void Main(string[] args)
        {
            var references = new List <string> ();
            var prefixes   = new List <string> ();

            List <string> files = new OptionSet {
                { "p|prefix|prefixes=",
                  "Mono installation prefixes (for $prefix/etc/mono/config)",
                  v => prefixes.Add(v) },
                { "r|reference|references=",
                  "Assemblies to load by partial names (e.g. from the GAC)",
                  v => references.Add(v) },
            }.Parse(args);

            AssemblyChecker   checker = new AssemblyChecker();
            AssemblyCheckInfo report  = new AssemblyCheckInfo();

            if (prefixes.Count == 0)
            {
                // SystemConfigurationFile is $sysconfdir/mono/VERSION/machine.config
                // We want $sysconfdir
                DirectoryInfo configDir =
                    new FileInfo(RuntimeEnvironment.SystemConfigurationFile).Directory.Parent.Parent.Parent;
                prefixes.Add(configDir.ToString());
            }
            report.SetInstallationPrefixes(prefixes);
            foreach (string assembly in files)
            {
                checker.CheckFile(assembly, report);
            }

            foreach (string assembly in references)
            {
                checker.CheckWithPartialName(assembly, report);
            }

            foreach (MessageInfo m in report.Errors)
            {
                PrintMessage("error", m);
            }

            foreach (MessageInfo m in report.Warnings)
            {
                PrintMessage("warning", m);
            }
        }
예제 #9
0
        private void CheckLibrary(MethodBase method, DllImportAttribute attribute,
                                  AssemblyCheckInfo report)
        {
            string library    = attribute.Value;
            string entrypoint = attribute.EntryPoint;
            string type       = method.DeclaringType.FullName;
            string mname      = method.Name;

            string found = null;
            string error = null;

            Trace.WriteLine("Trying to load base library: " + library);

            foreach (string name in GetLibraryNames(method.DeclaringType, library, report))
            {
                if (LoadLibrary(type, mname, name, entrypoint, report, out error))
                {
                    found = name;
                    break;
                }
            }

            if (found == null)
            {
                report.Errors.Add(new MessageInfo(
                                      type, mname,
                                      "Could not load library `" + library + "': " + error));
                return;
            }

            // UnixFileInfo f = new UnixFileInfo (soname);
            if (found.EndsWith(".so"))
            {
                report.Warnings.Add(new MessageInfo(type, mname,
                                                    string.Format("Library `{0}' might be a development library",
                                                                  found)));
            }
        }
예제 #10
0
		public void CheckFile (string file, AssemblyCheckInfo report)
		{
			try {
				Check (Assembly.LoadFile (file), report);
			}
			catch (FileNotFoundException e) {
				report.Errors.Add (new MessageInfo (null, null, 
					"Could not load `" + file + "': " + e.Message));
			}
		}
예제 #11
0
		private void Check (Assembly a, AssemblyCheckInfo report)
		{
			foreach (Type t in a.GetTypes ()) {
				Check (t, report);
			}
		}
예제 #12
0
		private void Check (Type type, AssemblyCheckInfo report)
		{
			BindingFlags bf = BindingFlags.Instance | BindingFlags.Static | 
				BindingFlags.Public | BindingFlags.NonPublic;

			foreach (MemberInfo mi in type.GetMembers (bf)) {
				CheckMember (type, mi, report);
			}
		}
예제 #13
0
		private void CheckMember (Type type, MemberInfo mi, AssemblyCheckInfo report)
		{
			DllImportAttribute[] attributes = null;
			MethodBase[] methods = null;
			switch (mi.MemberType) {
				case MemberTypes.Constructor: case MemberTypes.Method: {
					MethodBase mb = (MethodBase) mi;
					attributes = new DllImportAttribute[]{GetDllImportInfo (mb)};
					methods = new MethodBase[]{mb};
					break;
				}
				case MemberTypes.Event: {
					EventInfo ei = (EventInfo) mi;
					MethodBase add = ei.GetAddMethod (true);
					MethodBase remove = ei.GetRemoveMethod (true);
					attributes = new DllImportAttribute[]{
						GetDllImportInfo (add), GetDllImportInfo (remove)};
					methods = new MethodBase[]{add, remove};
					break;
				}
				case MemberTypes.Property: {
					PropertyInfo pi = (PropertyInfo) mi;
					MethodInfo[] accessors = pi.GetAccessors (true);
					if (accessors == null)
						break;
					attributes = new DllImportAttribute[accessors.Length];
					methods = new MethodBase [accessors.Length];
					for (int i = 0; i < accessors.Length; ++i) {
						attributes [i] = GetDllImportInfo (accessors [i]);
						methods [i] = accessors [i];
					}
					break;
				}
			}
			if (attributes == null || methods == null)
				return;

			for (int i = 0; i < attributes.Length; ++i) {
				if (attributes [i] == null)
					continue;
				CheckLibrary (methods [i], attributes [i], report);
			}
		}
예제 #14
0
		private void CheckLibrary (MethodBase method, DllImportAttribute attribute, 
				AssemblyCheckInfo report)
		{
			string library = attribute.Value;
			string entrypoint = attribute.EntryPoint;
			string type = method.DeclaringType.FullName;
			string mname = method.Name;

			string found = null;
			string error = null;

			Trace.WriteLine ("Trying to load base library: " + library);

			foreach (string name in GetLibraryNames (method.DeclaringType, library, report)) {
				if (LoadLibrary (type, mname, name, entrypoint, report, out error)) {
					found = name;
					break;
				}
			}

			if (found == null) {
				report.Errors.Add (new MessageInfo (
							type, mname,
							"Could not load library `" + library + "': " + error));
				return;
			}

			// UnixFileInfo f = new UnixFileInfo (soname);
			if (found.EndsWith (".so")) {
				report.Warnings.Add (new MessageInfo (type, mname, 
						string.Format ("Library `{0}' might be a development library",
							found)));
			}
		}
예제 #15
0
		private static string[] GetLibraryNames (Type type, string library, AssemblyCheckInfo report)
		{
			// TODO: keep in sync with
			// mono/metadata/loader.c:mono_lookup_pinvoke_call
			ArrayList names = new ArrayList ();

			string dll_map = report.GetDllmapEntry (type.Assembly.Location, library);
			if (dll_map != null) 
				names.Add (dll_map);

			names.Add (library);
			int _dll_index = library.LastIndexOf (".dll");
			if (_dll_index >= 0)
				names.Add (library.Substring (0, _dll_index));

			if (!library.StartsWith ("lib"))
				names.Add ("lib" + library);

			IntPtr s = g_module_build_path (null, library);
			if (s != IntPtr.Zero) {
				try {
					names.Add (Marshal.PtrToStringAnsi (s));
				}
				finally {
					g_free (s);
				}
			}

			s = g_module_build_path (".", library);
			if (s != IntPtr.Zero) {
				try {
					names.Add (Marshal.PtrToStringAnsi (s));
				}
				finally {
					g_free (s);
				}
			}

			return (string[]) names.ToArray (typeof(string));
		}
예제 #16
0
		private static bool LoadLibrary (string type, string member, 
				string library, string symbol, AssemblyCheckInfo report, out string error)
		{
			error = null;
			IntPtr h = g_module_open (library, 
					G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
			try {
				Trace.WriteLine ("    Trying library name: " + library);
				if (h != IntPtr.Zero) {
					string soname = Marshal.PtrToStringAnsi (g_module_name (h));
					Trace.WriteLine ("Able to load library " + library + 
							"; soname=" + soname);
					IntPtr ignore;
					if (g_module_symbol (h, symbol, out ignore) == 0)
						report.Errors.Add (new MessageInfo (
								type, member,
								string.Format ("library `{0}' is missing symbol `{1}'",
									library, symbol)));
					return true;
				}
				error = Marshal.PtrToStringAnsi (g_module_error ());
				Trace.WriteLine ("\tError loading library `" + library + "': " + error);
			}
			finally {
				if (h != IntPtr.Zero)
					g_module_close (h);
			}
			return false;
		}
예제 #17
0
		public void CheckWithPartialName (string partial, AssemblyCheckInfo report)
		{
			string p = partial;
			Assembly a;
			bool retry;

			do {
				a = Assembly.LoadWithPartialName (p);
				retry = p.EndsWith (".dll");
				if (retry) {
					p = p.Substring (0, p.Length-4);
				}
			} while (a == null && retry);

			if (a == null) {
				report.Errors.Add (new MessageInfo (null, null, 
					"Could not load assembly reference `" + partial + "'."));
				return;
			}

			Check (a, report);
		}
예제 #18
0
		public static void Main (string[] args)
		{
			var references = new List<string> ();
			var prefixes   = new List<string> ();

			List<string> files = new OptionSet {
				{ "p|prefix|prefixes=",
				  "Mono installation prefixes (for $prefix/etc/mono/config)",
				  v => prefixes.Add (v) },
				{ "r|reference|references=",
				  "Assemblies to load by partial names (e.g. from the GAC)",
					v => references.Add (v) },
			}.Parse (args);

			AssemblyChecker checker = new AssemblyChecker ();
			AssemblyCheckInfo report = new AssemblyCheckInfo ();
			if (prefixes.Count == 0) {
				// SystemConfigurationFile is $sysconfdir/mono/VERSION/machine.config
				// We want $sysconfdir
				DirectoryInfo configDir = 
					new FileInfo (RuntimeEnvironment.SystemConfigurationFile).Directory.Parent.Parent.Parent;
				prefixes.Add (configDir.ToString ());
			}
			report.SetInstallationPrefixes (prefixes);
			foreach (string assembly in files) {
				checker.CheckFile (assembly, report);
			}

			foreach (string assembly in references) {
				checker.CheckWithPartialName (assembly, report);
			}

			foreach (MessageInfo m in report.Errors) {
				PrintMessage ("error", m);
			}

			foreach (MessageInfo m in report.Warnings) {
				PrintMessage ("warning", m);
			}
		}