2
0
Эх сурвалжийг харах

Add link-time library loader

Which does not call dlsym or equivalents, but links directly against the library and dispatches on name.
This can be useful on platforms without (working) dlsym-implementations, without affecting the structure of lua-https too much.
Bart van Strien 1 жил өмнө
parent
commit
56a1ed18c9

+ 9 - 1
src/CMakeLists.txt

@@ -51,6 +51,10 @@ add_library (https-unix-libraryloader STATIC EXCLUDE_FROM_ALL
 	generic/UnixLibraryLoader.cpp
 )
 
+add_library (https-linktime-libraryloader STATIC EXCLUDE_FROM_ALL
+	generic/LinktimeLibraryLoader.cpp
+)
+
 add_library (https-curl STATIC EXCLUDE_FROM_ALL
 	generic/CurlClient.cpp
 )
@@ -137,7 +141,7 @@ elseif (ANDROID)
 endif ()
 option (DEBUG_SCHANNEL "Enable debug output in schannel backend" OFF)
 set (LIBRARY_LOADER ${LIBRARY_LOADER_DEFAULT} CACHE STRING "Which method to use to dynamically load libraries")
-set_property (CACHE LIBRARY_LOADER PROPERTY STRINGS "unix;windows")
+set_property (CACHE LIBRARY_LOADER PROPERTY STRINGS "unix;windows;linktime")
 
 set_target_properties(https PROPERTIES PREFIX "")
 
@@ -148,6 +152,7 @@ if (USE_CURL_BACKEND)
 	find_package (CURL REQUIRED)
 	include_directories (${CURL_INCLUDE_DIRS})
 	target_link_libraries (https https-curl)
+	target_link_libraries (https-linktime-libraryloader ${CURL_LIBRARY})
 endif ()
 
 if (USE_OPENSSL_BACKEND)
@@ -195,6 +200,9 @@ if ("${LIBRARY_LOADER}" STREQUAL "unix")
 elseif ("${LIBRARY_LOADER}" STREQUAL "windows")
 	set(HTTPS_LIBRARY_LOADER_WINDOWS ON)
 	target_link_libraries (https https-windows-libraryloader)
+elseif ("${LIBRARY_LOADER}" STREQUAL "linktime")
+	set(HTTPS_LIBRARY_LOADER_LINKTIME ON)
+	target_link_libraries (https https-linktime-libraryloader)
 else ()
 	message(WARNING "No library loader selected, backends that depend on dynamic loading will be broken")
 endif ()

+ 1 - 0
src/common/config-generated.h.in

@@ -8,3 +8,4 @@
 #cmakedefine DEBUG_SCHANNEL
 #cmakedefine HTTPS_LIBRARY_LOADER_WINDOWS
 #cmakedefine HTTPS_LIBRARY_LOADER_UNIX
+#cmakedefine HTTPS_LIBRARY_LOADER_LINKTIME

+ 66 - 0
src/generic/LinktimeLibraryLoader.cpp

@@ -0,0 +1,66 @@
+#include "../common/config.h"
+#include "../common/LibraryLoader.h"
+
+#ifdef HTTPS_LIBRARY_LOADER_LINKTIME
+
+#include <cstring>
+
+#ifdef HTTPS_BACKEND_CURL
+#include <curl/curl.h>
+
+static char CurlHandle;
+#endif
+
+#if defined(HTTPS_BACKEND_OPENSSL) || defined(HTTPS_BACKEND_ANDROID)
+#	error "Selected backends that are not compatible with this loader"
+#endif
+
+namespace LibraryLoader
+{
+	handle *OpenLibrary(const char *name)
+	{
+#ifdef HTTPS_BACKEND_CURL
+		if (strstr(name, "libcurl") == name)
+			return reinterpret_cast<handle *>(&CurlHandle);
+#endif
+		return nullptr;
+	}
+
+	void CloseLibrary(handle *)
+	{
+	}
+
+	handle* GetCurrentProcessHandle()
+	{
+		return nullptr;
+	}
+
+	function *GetFunction(handle *handle, const char *name)
+	{
+#define RETURN_MATCHING_FUNCTION(func) \
+	if (strcmp(name, #func) == 0) \
+		return reinterpret_cast<function *>(&func);
+
+#ifdef HTTPS_BACKEND_CURL
+		if (handle == &CurlHandle)
+		{
+			RETURN_MATCHING_FUNCTION(curl_global_init);
+			RETURN_MATCHING_FUNCTION(curl_global_cleanup);
+			RETURN_MATCHING_FUNCTION(curl_easy_init);
+			RETURN_MATCHING_FUNCTION(curl_easy_cleanup);
+			RETURN_MATCHING_FUNCTION(curl_easy_setopt);
+			RETURN_MATCHING_FUNCTION(curl_easy_perform);
+			RETURN_MATCHING_FUNCTION(curl_easy_getinfo);
+			RETURN_MATCHING_FUNCTION(curl_slist_append);
+			RETURN_MATCHING_FUNCTION(curl_slist_free_all);
+		}
+#endif
+
+#undef RETURN_MATCHING_FUNCTION
+
+		return nullptr;
+	}
+}
+
+#endif // HTTPS_LIBRARY_LOADER_LINKTIME
+