@@ -58,32 +58,72 @@ public static void MemCopy(IntPtr destination, IntPtr source, IntPtr length) {
5858 }
5959
6060 // unix entry points, VM needs to map the filenames.
61- [ DllImport ( "libdl " ) ]
61+ [ DllImport ( "libc " ) ]
6262 private static extern IntPtr dlopen ( string filename , int flags ) ;
6363
64- [ DllImport ( "libdl" ) ]
64+ [ DllImport ( "libdl" , EntryPoint = "dlopen" ) ]
65+ private static extern IntPtr dlopen_dl ( string filename , int flags ) ;
66+
67+ [ DllImport ( "libc" ) ]
6568 private static extern IntPtr dlsym ( IntPtr handle , string symbol ) ;
6669
70+ [ DllImport ( "libdl" , EntryPoint = "dlsym" ) ]
71+ private static extern IntPtr dlsym_dl ( IntPtr handle , string symbol ) ;
72+
73+ [ DllImport ( "libc" ) ]
74+ private static extern IntPtr gnu_get_libc_version ( ) ;
75+
76+ private static bool GetGNULibCVersion ( out int major , out int minor ) {
77+ major = minor = 0 ;
78+ try {
79+ string ver = Marshal . PtrToStringAnsi ( gnu_get_libc_version ( ) ) ;
80+ int dot = ver . IndexOf ( '.' ) ;
81+ if ( dot < 0 ) dot = ver . Length ;
82+ if ( ! int . TryParse ( ver . Substring ( 0 , dot ) , out major ) ) return false ;
83+ if ( dot + 1 < ver . Length ) {
84+ if ( ! int . TryParse ( ver . Substring ( dot + 1 ) , out minor ) ) return false ;
85+ }
86+ } catch {
87+ return false ;
88+ }
89+ return true ;
90+ }
91+
6792 private const int RTLD_NOW = 2 ;
6893
94+ private static bool UseLibDL ( ) {
95+ if ( ! _useLibDL . HasValue ) {
96+ bool success = GetGNULibCVersion ( out int major , out int minor ) ;
97+ _useLibDL = ! success || major < 2 || ( major == 2 && minor < 34 ) ;
98+ }
99+ return _useLibDL . Value ;
100+ }
101+ private static bool ? _useLibDL ;
102+
69103 public static IntPtr LoadDLL ( string filename , int flags ) {
70- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) ||
71- RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
72- if ( flags == 0 )
73- flags = RTLD_NOW ;
74- return dlopen ( filename , flags ) ;
104+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) {
105+ return LoadLibrary ( filename ) ;
106+ }
107+
108+ if ( flags == 0 ) flags = RTLD_NOW ;
109+
110+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) && UseLibDL ( ) ) {
111+ return dlopen_dl ( filename , flags ) ;
75112 }
76113
77- return LoadLibrary ( filename ) ;
114+ return dlopen ( filename , flags ) ;
78115 }
79116
80117 public static IntPtr LoadFunction ( IntPtr module , string functionName ) {
81- if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) ||
82- RuntimeInformation . IsOSPlatform ( OSPlatform . OSX ) ) {
83- return dlsym ( module , functionName ) ;
118+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Windows ) ) {
119+ return GetProcAddress ( module , functionName ) ;
120+ }
121+
122+ if ( RuntimeInformation . IsOSPlatform ( OSPlatform . Linux ) && UseLibDL ( ) ) {
123+ return dlsym_dl ( module , functionName ) ;
84124 }
85125
86- return GetProcAddress ( module , functionName ) ;
126+ return dlsym ( module , functionName ) ;
87127 }
88128
89129 public static IntPtr LoadFunction ( IntPtr module , IntPtr ordinal ) {
0 commit comments