◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
109 changes: 109 additions & 0 deletions src/runtime/platform/LibDL.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
104 changes: 12 additions & 92 deletions src/runtime/platform/LibraryLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ public static ILibraryLoader Instance
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
_instance = new WindowsLoader();
else if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
_instance = new LinuxLoader();
else if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
_instance = new DarwinLoader();
else
throw new PlatformNotSupportedException(
"This operating system is not supported"
Expand All @@ -42,87 +42,19 @@ public static ILibraryLoader Instance
}
}

class LinuxLoader : ILibraryLoader
{
private static int RTLD_NOW = 0x2;
private static int RTLD_GLOBAL = 0x100;
private static IntPtr RTLD_DEFAULT = IntPtr.Zero;
private const string NativeDll = "libdl.so";

public IntPtr Load(string dllToLoad)
{
ClearError();
var res = dlopen(dllToLoad, RTLD_NOW | RTLD_GLOBAL);
if (res == IntPtr.Zero)
{
var err = GetError();
throw new DllNotFoundException($"Could not load {dllToLoad} with flags RTLD_NOW | RTLD_GLOBAL: {err}");
}

return res;
}

public void Free(IntPtr handle)
{
dlclose(handle);
}

public IntPtr GetFunction(IntPtr dllHandle, string name)
{
// look in the exe if dllHandle is NULL
if (dllHandle == IntPtr.Zero)
{
dllHandle = RTLD_DEFAULT;
}

ClearError();
IntPtr res = dlsym(dllHandle, name);
if (res == IntPtr.Zero)
{
var err = GetError();
throw new MissingMethodException($"Failed to load symbol {name}: {err}");
}
return res;
}

void ClearError()
{
dlerror();
}

string GetError()
{
var res = dlerror();
if (res != IntPtr.Zero)
return Marshal.PtrToStringAnsi(res);
else
return null;
}

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr dlopen(string fileName, int flags);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern IntPtr dlsym(IntPtr handle, string symbol);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int dlclose(IntPtr handle);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr dlerror();
}

class DarwinLoader : ILibraryLoader
{
private static int RTLD_NOW = 0x2;
private static int RTLD_GLOBAL = 0x8;
private const string NativeDll = "/usr/lib/libSystem.dylib";
private static IntPtr RTLD_DEFAULT = new IntPtr(-2);

public IntPtr Load(string dllToLoad)
{
ClearError();
var res = dlopen(dllToLoad, RTLD_NOW | RTLD_GLOBAL);
if (res == IntPtr.Zero)
{
var err = GetError();
Expand All @@ -134,19 +66,19 @@ public IntPtr Load(string dllToLoad)

public void Free(IntPtr handle)
{
dlclose(handle);
}

public IntPtr GetFunction(IntPtr dllHandle, string name)
{
// look in the exe if dllHandle is NULL
if (dllHandle == IntPtr.Zero)
{
dllHandle = RTLD_DEFAULT;
}

ClearError();
IntPtr res = dlsym(dllHandle, name);
if (res == IntPtr.Zero)
{
var err = GetError();
Expand All @@ -157,29 +89,17 @@ public IntPtr GetFunction(IntPtr dllHandle, string name)

void ClearError()
{
dlerror();
}

string GetError()
{
var res = dlerror();
if (res != IntPtr.Zero)
return Marshal.PtrToStringAnsi(res);
else
return null;
}

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
public static extern IntPtr dlopen(String fileName, int flags);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)]
private static extern IntPtr dlsym(IntPtr handle, String symbol);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)]
private static extern int dlclose(IntPtr handle);

[DllImport(NativeDll, CallingConvention = CallingConvention.Cdecl)]
private static extern IntPtr dlerror();
}

class WindowsLoader : ILibraryLoader
Expand Down
Toggle all file notes Toggle all file annotations