Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Move dlopen and dlsym to PAL #25134

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions src/Common/src/Interop/Unix/System.Native/Interop.DlOpen.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using System;
using System.Runtime.InteropServices;

internal static partial class Interop
{
internal static partial class Sys
{
[Flags]
internal enum DlOpenFlags : int
{
RTLD_LAZY = 1,
RTLD_NOW = 2
}

[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_DlOpen")]
internal static extern IntPtr DlOpen(string fileName, DlOpenFlags flag);
Copy link
Member

@stephentoub stephentoub Nov 8, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like dlopen is also being used in tests, e.g.

nativeLib = dlopen("libgdiplus.so", RTLD_NOW);

Interop.Libdl.dlopen((

Do those need to be fixed?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated both usages of dlopen. I couldn't find any other places that use dlopen so I think we're good now.

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
using System;
using System.Runtime.InteropServices;

internal partial class Interop
internal static partial class Interop
{
internal partial class Libdl
internal static partial class Sys
{
public const int RTLD_NOW = 0x002;

[DllImport(Libraries.Libdl)]
public static extern IntPtr dlopen(string fileName, int flag);
[DllImport(Libraries.SystemNative, EntryPoint = "SystemNative_DlSym")]
internal static extern IntPtr DlSym(IntPtr handle, string symbol);
}
}
15 changes: 0 additions & 15 deletions src/Common/src/Interop/Unix/libdl/Interop.dlsym.cs

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ namespace System.Runtime.InteropServices
internal static partial class FunctionWrapper
{
public static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName)
=> Interop.Libdl.dlsym(nativeLibraryHandle, functionName);
=> Interop.Sys.DlSym(nativeLibraryHandle, functionName);
}
}
1 change: 1 addition & 0 deletions src/Native/Unix/System.Native/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ set(NATIVE_SOURCES
pal_uid.cpp
pal_datetime.cpp
pal_sysctl.cpp
pal_dl.cpp
)

if (CMAKE_SYSTEM_NAME STREQUAL Linux)
Expand Down
20 changes: 20 additions & 0 deletions src/Native/Unix/System.Native/pal_dl.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#include <dlfcn.h>
#include "pal_dl.h"

// Validate that our definitions match those used by the OS.
static_assert(PAL_RTLD_LAZY == RTLD_LAZY, "");
static_assert(PAL_RTLD_NOW == RTLD_NOW, "");

extern "C" void* SystemNative_DlOpen(const char *file, int mode)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally we try to avoid just assuming that these values are the same on all platforms, e.g. that RTLD_GLOBAL is 4 everywhere. Two options:

  1. Switch on mode, accepting the values we use in .NET, and use that to determine the actual value to pass to dlopen.
  2. Use static_asserts to validate the values we're using for mode match the platform at compile time.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I limited the values to RTLD_LAZY and RTLD_NOW, added PAL_ equivalents and added static_asserts to validate the values at compile time.

{
return dlopen(file, mode);
}

extern "C" void* SystemNative_DlSym(void *handle, const char *name)
{
return dlsym(handle, name);
}
26 changes: 26 additions & 0 deletions src/Native/Unix/System.Native/pal_dl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

#pragma once

// Values for the mode flag in dlopen
enum
{
PAL_RTLD_LAZY = 1,
PAL_RTLD_NOW = 2
};

/**
* Loads a dynamic library file. Implemented as shim to dlopen(3).
*
* An opaque handle for the dynamic library, or null on failure.
*/
extern "C" void* SystemNative_DlOpen(const char *file, int mode);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.


/**
* Gets, for a given dynamic library, the address of a symbol in that library. Implemented as shim to dlopen(3).
*
* The address of the symbol, or null on failure.
*/
extern "C" void* SystemNative_DlSym(void *handle, const char *name);
4 changes: 2 additions & 2 deletions src/System.Data.Odbc/tests/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ public static class Helpers
private static bool CheckOdbcIsAvailable() =>
PlatformDetection.IsWindows ?
!PlatformDetection.IsWindowsNanoServer && (!PlatformDetection.IsWindowsServerCore || Environment.Is64BitProcess ) :
Interop.Libdl.dlopen((
Interop.Sys.DlOpen((
PlatformDetection.IsOSX ?
"libodbc.2.dylib" :
"libodbc.so.2"
), Interop.Libdl.RTLD_NOW) != IntPtr.Zero;
), Interop.Sys.DlOpenFlags.RTLD_NOW) != IntPtr.Zero;
}
}
4 changes: 2 additions & 2 deletions src/System.Data.Odbc/tests/System.Data.Odbc.Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlopen.cs">
<Link>Common\Interop\Unix\libdl\Interop.dlopen.cs</Link>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.DlOpen.cs">
<Link>Common\Interop\Unix\libdl\Interop.DlOpen.cs</Link>
</Compile>
<Compile Include="TestCommon\DataTestUtility.cs" />
<Compile Include="TestCommon\CheckConnStrSetupFactAttribute.cs" />
Expand Down
8 changes: 4 additions & 4 deletions src/System.Drawing.Common/src/System.Drawing.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -328,11 +328,11 @@
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlopen.cs">
<Link>Common\Interop\Unix\libdl\Interop.dlopen.cs</Link>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.DlOpen.cs">
<Link>Common\Interop\Unix\System.Native\Interop.DlOpen.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\libdl\Interop.dlsym.cs">
<Link>Common\Interop\Unix\libdl\Interop.dlsym.cs</Link>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.DlSym.cs">
<Link>Common\Interop\Unix\System.Native\Interop.DlSym.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\System\Runtime\InteropServices\FunctionWrapper.Unix.cs">
<Link>Common\System\Runtime\InteropServices\FunctionWrapper.Unix.cs</Link>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,18 @@ private static IntPtr LoadNativeLibrary()
IntPtr lib = IntPtr.Zero;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
lib = Interop.Libdl.dlopen("libgdiplus.dylib", Interop.Libdl.RTLD_NOW);
lib = Interop.Sys.DlOpen("libgdiplus.dylib", Interop.Sys.DlOpenFlags.RTLD_NOW);
}
else
{
// Various Unix package managers have chosen different names for the "libgdiplus" shared library.
// The mono project, where libgdiplus originated, allowed both of the names below to be used, via
// a global configuration setting. We prefer the "unversioned" shared object name, and fallback to
// the name suffixed with ".0".
lib = Interop.Libdl.dlopen("libgdiplus.so", Interop.Libdl.RTLD_NOW);
lib = Interop.Sys.DlOpen("libgdiplus.so", Interop.Sys.DlOpenFlags.RTLD_NOW);
if (lib == IntPtr.Zero)
{
lib = Interop.Libdl.dlopen("libgdiplus.so.0", Interop.Libdl.RTLD_NOW);
lib = Interop.Sys.DlOpen("libgdiplus.so.0", Interop.Sys.DlOpenFlags.RTLD_NOW);
}
}

Expand All @@ -44,7 +44,7 @@ private static IntPtr LoadNativeLibrary()
return lib;
}

private static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName) => Interop.Libdl.dlsym(nativeLibraryHandle, functionName);
private static IntPtr LoadFunctionPointer(IntPtr nativeLibraryHandle, string functionName) => Interop.Sys.DlSym(nativeLibraryHandle, functionName);

private static void PlatformInitialize()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ internal static class LibcupsNative
private static IntPtr LoadLibcups()
{
// We allow both "libcups.so" and "libcups.so.2" to be loaded.
IntPtr lib = Interop.Libdl.dlopen("libcups.so", Interop.Libdl.RTLD_NOW);
IntPtr lib = Interop.Sys.DlOpen("libcups.so", Interop.Sys.DlOpenFlags.RTLD_NOW);
if (lib == IntPtr.Zero)
{
lib = Interop.Libdl.dlopen("libcups.so.2", Interop.Libdl.RTLD_NOW);
lib = Interop.Sys.DlOpen("libcups.so.2", Interop.Sys.DlOpenFlags.RTLD_NOW);
}

return lib;
Expand Down
10 changes: 3 additions & 7 deletions src/System.Drawing.Common/tests/Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,14 +30,14 @@ public static bool GetGdiplusIsAvailable()
IntPtr nativeLib;
if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
{
nativeLib = dlopen("libgdiplus.dylib", RTLD_NOW);
nativeLib = Interop.Sys.DlOpen("libgdiplus.dylib", Interop.Sys.DlOpenFlags.RTLD_NOW);
}
else
{
nativeLib = dlopen("libgdiplus.so", RTLD_NOW);
nativeLib = Interop.Sys.DlOpen("libgdiplus.so", Interop.Sys.DlOpenFlags.RTLD_NOW);
if (nativeLib == IntPtr.Zero)
{
nativeLib = dlopen("libgdiplus.so.0", RTLD_NOW);
nativeLib = Interop.Sys.DlOpen("libgdiplus.so.0", Interop.Sys.DlOpenFlags.RTLD_NOW);
}
}

Expand Down Expand Up @@ -92,10 +92,6 @@ public static bool IsAnyInstalledPrinters()
return PrinterSettings.InstalledPrinters.Count > 0;
}

[DllImport("libdl")]
private static extern IntPtr dlopen(string libName, int flags);
public const int RTLD_NOW = 0x002;

public static string GetTestBitmapPath(string fileName) => GetTestPath("bitmaps", fileName);
public static string GetTestFontPath(string fileName) => GetTestPath("fonts", fileName);
public static string GetTestColorProfilePath(string fileName) => GetTestPath("colorProfiles", fileName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Debug|AnyCPU'" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netfx-Release|AnyCPU'" />
<ItemGroup>
<Compile Include="$(CommonPath)\Interop\Unix\System.Native\Interop.DlOpen.cs">
<Link>Common\Interop\Unix\System.Native\Interop.DlOpen.cs</Link>
</Compile>
<Compile Include="$(CommonPath)\Interop\Unix\Interop.Libraries.cs">
<Link>Common\Interop\Unix\Interop.Libraries.cs</Link>
</Compile>
<Compile Include="BitmapTests.cs" />
<Compile Include="BrushTests.cs" />
<Compile Include="BrushesTests.cs" />
Expand Down