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); }
private void Check(Assembly a, AssemblyCheckInfo report) { foreach (Type t in a.GetTypes()) { Check(t, report); } }
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); }
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); } }
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); } }
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)); } }
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))); }
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); } }
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))); } }
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)); } }
private void Check (Assembly a, AssemblyCheckInfo report) { foreach (Type t in a.GetTypes ()) { Check (t, report); } }
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); } }
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); } }
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))); } }
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)); }
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; }
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); }
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); } }