Branch: master

af8244e3 2018-06-16 07:45:03 Michele Calgaro
Fixed problem with dlsym lookup. This resolve bug 2477.
Partially inspired by posts at
https://stackoverflow.com/questions/15599026/how-can-i-intercept-dlsym-calls-using-ld-preload

Signed-off-by: Michele Calgaro <michele.calgaro@...>
M gtk2/kgtk2.c
M tqt/kqt3.cpp

gtk2/kgtk2.c

diff --git a/gtk2/kgtk2.c b/gtk2/kgtk2.c
index 77d690b..3b4889e 100644
--- a/gtk2/kgtk2.c
+++ b/gtk2/kgtk2.c
@@ -67,10 +67,6 @@
 #include "connect.h"
 #include "config.h"
 
-#ifndef KGTK_DLSYM_VERSION
-#define KGTK_DLSYM_VERSION "GLIBC_2.0"
-#endif
-
 #define BLACKLIST_UNKNOWN_GTK_APPS 0
 
 /*
@@ -78,15 +74,10 @@
 */
 
 /*
- * For SWT apps (e.g. eclipse) we need to override dlsym, but we can only do this if
- * dlvsym is present in libdl. dlvsym is needed so that we can access the real dlsym
- * as well as our fake dlsym
+ * For SWT apps (e.g. eclipse) we need to override dlsym.
  */
-#ifdef HAVE_DLVSYM
+extern void *_dl_sym(void *, const char *, void *);
 static void * real_dlsym (void *handle, const char *name);
-#else
-#define real_dlsym(A, B) dlsym(A, B)
-#endif
 
 typedef enum
 {
@@ -2241,41 +2232,38 @@
         return NULL;
 }
 
-#ifdef HAVE_DLVSYM
 /* Overriding dlsym is required for SWT - which dlsym's the gtk_file_chooser functions! */
 static void * real_dlsym(void *handle, const char *name)
 {
-    static void * (*realFunction)() = NULL;
+	static void * (*realFunction)() = NULL;
 
 #ifdef KGTK_DEBUG_DLSYM
-    printf("KGTK::real_dlsym : %s\n", name);
+	printf("KGTK::real_dlsym : %s\n", name);
 #endif
 
-    if (!realFunction)
-    {
-        void *ldHandle=dlopen("libdl.so", RTLD_NOW);
+	if (!realFunction)
+	{
+		// Get the real dlsym function
+		realFunction = _dl_sym(RTLD_NEXT, "dlsym", dlsym);
+	}
 
-#ifdef KGTK_DEBUG_DLSYM
-        printf("KGTK::real_dlsym : %s\n", name);
-#endif
-
-        if(ldHandle)
-        {
-            static const char * versions[]={KGTK_DLSYM_VERSION, "GLIBC_2.3", "GLIBC_2.2.5",
-                                            "GLIBC_2.2", "GLIBC_2.1", "GLIBC_2.0", NULL};
-
-            int i;
-
-            for(i=0; versions[i] && !realFunction; ++i)
-                realFunction=dlvsym(ldHandle, "dlsym", versions[i]);
-        }
-    }
-
-    return realFunction(handle, name);
+	if (realFunction)
+		return realFunction(handle, name);
+	else
+	{
+		printf("kgtk-qt3 gtk2 real_dlsymc() realFunction not found!!\n");
+		return NULL;
+	}
 }
 
 void * dlsym(void *handle, const char *name)
 {
+		// Need this so _dl_sym will be able to find the next dlsym, i.e. the real dlsym!
+		if (!strcmp(name, "dlsym"))
+		{
+			return (void*)dlsym;
+		}
+
     void *rv=NULL;
 
 #ifdef KGTK_DEBUG_DLSYM
@@ -2294,4 +2282,3 @@
 #endif
     return rv;
 }
-#endif

tqt/kqt3.cpp

diff --git a/tqt/kqt3.cpp b/tqt/kqt3.cpp
index 8ceb265..97b3584 100644
--- a/tqt/kqt3.cpp
+++ b/tqt/kqt3.cpp
@@ -120,19 +120,25 @@
 
 int TQApplication::exec()
 {
-    static bool init=false;
+	static bool init=false;
 
-    if(!init)
-    {
-        connectToKDialogD(getAppName(false));
-        init=true;
-    }
+	if(!init)
+	{
+		connectToKDialogD(getAppName(false));
+		init=true;
+	}
 
-    static int (*realFunction)(void *);
+	static int (*realFunction)(void *);
 
-    if(!realFunction)
-        realFunction = (int (*)(void *)) dlsym(RTLD_NEXT, KQT_QAPPLICATION_EXEC);
-    return (int)realFunction(this);
+	if(!realFunction)
+		realFunction = (int (*)(void *)) dlsym(RTLD_NEXT, KQT_QAPPLICATION_EXEC);
+	if (realFunction)
+		return (int)realFunction(this);
+	else
+	{
+		tqWarning("kgtk-qt3 tqt TQApplication::exec() realFunction not found!!");
+		return 255;
+	}
 };
 
 static TQString qt2KdeFilter(const TQString &f)