@@ -58,32 +58,72 @@ public static void MemCopy(IntPtr destination, IntPtr source, IntPtr length) {
58
58
}
59
59
60
60
// unix entry points, VM needs to map the filenames.
61
- [ DllImport ( "libdl " ) ]
61
+ [ DllImport ( "libc " ) ]
62
62
private static extern IntPtr dlopen ( string filename , int flags ) ;
63
63
64
- [ DllImport ( "libdl" ) ]
64
+ [ DllImport ( "libdl" , EntryPoint = "dlopen" ) ]
65
+ private static extern IntPtr dlopen_dl ( string filename , int flags ) ;
66
+
67
+ [ DllImport ( "libc" ) ]
65
68
private static extern IntPtr dlsym ( IntPtr handle , string symbol ) ;
66
69
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
+
67
92
private const int RTLD_NOW = 2 ;
68
93
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
+
69
103
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 ) ;
75
112
}
76
113
77
- return LoadLibrary ( filename ) ;
114
+ return dlopen ( filename , flags ) ;
78
115
}
79
116
80
117
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 ) ;
84
124
}
85
125
86
- return GetProcAddress ( module , functionName ) ;
126
+ return dlsym ( module , functionName ) ;
87
127
}
88
128
89
129
public static IntPtr LoadFunction ( IntPtr module , IntPtr ordinal ) {
0 commit comments