Use an internal symbol to determine library directory.

Exported symbols with protected visibility (change made in the next
patch) have a relocation type that is incompatible with passing their
address to dladdr(). Instead we can use a static local variable.

Bug b/110884149

Change-Id: I3e38280276ec00913b28ff97b007490619a99f58
Reviewed-on: https://swiftshader-review.googlesource.com/19710
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Common/SharedLibrary.hpp b/src/Common/SharedLibrary.hpp
index 39945f3..8a8c3a1 100644
--- a/src/Common/SharedLibrary.hpp
+++ b/src/Common/SharedLibrary.hpp
@@ -89,10 +89,13 @@
 		return (void*)GetProcAddress((HMODULE)library, name);
 	}
 
-	inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+	inline std::string getModuleDirectory()
 	{
+		static int dummy_symbol = 0;
+
 		HMODULE module = NULL;
-		GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)symbol, &module);
+		GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCTSTR)&dummy_symbol, &module);
+
 		char filename[1024];
 		if(module && (GetModuleFileName(module, filename, sizeof(filename)) != 0))
 		{
@@ -148,10 +151,12 @@
 		return symbol;
 	}
 
-	inline std::string getLibraryDirectoryFromSymbol(void* symbol)
+	inline std::string getModuleDirectory()
 	{
+		static int dummy_symbol = 0;
+
 		Dl_info dl_info;
-		if(dladdr(symbol, &dl_info) != 0)
+		if(dladdr(&dummy_symbol, &dl_info) != 0)
 		{
 			std::string directory(dl_info.dli_fname);
 			return directory.substr(0, directory.find_last_of("\\/") + 1).c_str();
diff --git a/src/OpenGL/libEGL/libEGL.hpp b/src/OpenGL/libEGL/libEGL.hpp
index 74ddf65..b6d9d63 100644
--- a/src/OpenGL/libEGL/libEGL.hpp
+++ b/src/OpenGL/libEGL/libEGL.hpp
@@ -73,7 +73,7 @@
 class LibEGL
 {
 public:
-	LibEGL(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
+	LibEGL()
 	{
 	}
 
@@ -118,7 +118,8 @@
 				#error "libEGL::loadExports unimplemented for this platform"
 			#endif
 
-			libEGL = loadLibrary(libraryDirectory, libEGL_lib, "libEGL_swiftshader");
+			std::string directory = getModuleDirectory();
+			libEGL = loadLibrary(directory, libEGL_lib, "libEGL_swiftshader");
 
 			if(libEGL)
 			{
@@ -132,7 +133,6 @@
 
 	void *libEGL = nullptr;
 	LibEGLexports *libEGLexports = nullptr;
-	const std::string libraryDirectory;
 };
 
 #endif   // libEGL_hpp
diff --git a/src/OpenGL/libEGL/main.cpp b/src/OpenGL/libEGL/main.cpp
index c850610..a1ff6f1 100644
--- a/src/OpenGL/libEGL/main.cpp
+++ b/src/OpenGL/libEGL/main.cpp
@@ -649,5 +649,5 @@
 	return &libEGL;
 }
 
-LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
-LibGLESv2 libGLESv2(getLibraryDirectoryFromSymbol((void*)libEGL_swiftshader));
+LibGLES_CM libGLES_CM;
+LibGLESv2 libGLESv2;
diff --git a/src/OpenGL/libGLES_CM/libGLES_CM.hpp b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
index 10b8e9a..ae6237b 100644
--- a/src/OpenGL/libGLES_CM/libGLES_CM.hpp
+++ b/src/OpenGL/libGLES_CM/libGLES_CM.hpp
@@ -229,7 +229,7 @@
 class LibGLES_CM
 {
 public:
-	LibGLES_CM(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
+	LibGLES_CM()
 	{
 	}
 
@@ -279,7 +279,8 @@
 				#error "libGLES_CM::loadExports unimplemented for this platform"
 			#endif
 
-			libGLES_CM = loadLibrary(libraryDirectory, libGLES_CM_lib, "libGLES_CM_swiftshader");
+			std::string directory = getModuleDirectory();
+			libGLES_CM = loadLibrary(directory, libGLES_CM_lib, "libGLES_CM_swiftshader");
 
 			if(libGLES_CM)
 			{
@@ -293,7 +294,6 @@
 
 	void *libGLES_CM = nullptr;
 	LibGLES_CMexports *libGLES_CMexports = nullptr;
-	const std::string libraryDirectory;
 };
 
 #endif   // libGLES_CM_hpp
diff --git a/src/OpenGL/libGLES_CM/main.cpp b/src/OpenGL/libGLES_CM/main.cpp
index ea56c81..f2bd0b7 100644
--- a/src/OpenGL/libGLES_CM/main.cpp
+++ b/src/OpenGL/libGLES_CM/main.cpp
@@ -1610,4 +1610,4 @@
 	return &libGLES_CM;
 }
 
-LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLES_CM_swiftshader));
+LibEGL libEGL;
diff --git a/src/OpenGL/libGLESv2/entry_points.cpp b/src/OpenGL/libGLESv2/entry_points.cpp
index fa52a8b..5460bcd 100644
--- a/src/OpenGL/libGLESv2/entry_points.cpp
+++ b/src/OpenGL/libGLESv2/entry_points.cpp
@@ -1426,5 +1426,5 @@
 	return &libGLESv2;
 }
 
-LibEGL libEGL(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
-LibGLES_CM libGLES_CM(getLibraryDirectoryFromSymbol((void*)libGLESv2_swiftshader));
+LibEGL libEGL;
+LibGLES_CM libGLES_CM;
diff --git a/src/OpenGL/libGLESv2/libGLESv2.hpp b/src/OpenGL/libGLESv2/libGLESv2.hpp
index cb16caf..247c6fa 100644
--- a/src/OpenGL/libGLESv2/libGLESv2.hpp
+++ b/src/OpenGL/libGLESv2/libGLESv2.hpp
@@ -254,7 +254,7 @@
 class LibGLESv2
 {
 public:
-	LibGLESv2(const std::string libraryDirectory) : libraryDirectory(libraryDirectory)
+	LibGLESv2()
 	{
 	}
 
@@ -304,7 +304,8 @@
 				#error "libGLESv2::loadExports unimplemented for this platform"
 			#endif
 
-			libGLESv2 = loadLibrary(libraryDirectory, libGLESv2_lib, "libGLESv2_swiftshader");
+			std::string directory = getModuleDirectory();
+			libGLESv2 = loadLibrary(directory, libGLESv2_lib, "libGLESv2_swiftshader");
 
 			if(libGLESv2)
 			{
@@ -318,7 +319,6 @@
 
 	void *libGLESv2 = nullptr;
 	LibGLESv2exports *libGLESv2exports = nullptr;
-	const std::string libraryDirectory;
 };
 
 #endif   // libGLESv2_hpp