5
5
#include "elf_ops.h"
6
6
#include <dlfcn.h>
7
7
8
+ #if defined(__GLIBC__ ) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 34
9
+ # define GOTCHA_DL_SYM_WORKAROUND 1
10
+ #endif
11
+
12
+ #ifndef GOTCHA_DL_SYM_WORKAROUND
8
13
void * _dl_sym (void * handle , const char * name , void * where );
14
+ #endif
9
15
10
16
gotcha_wrappee_handle_t orig_dlopen_handle ;
11
17
gotcha_wrappee_handle_t orig_dlsym_handle ;
@@ -17,13 +23,13 @@ static int per_binding(hash_key_t key, hash_data_t data, void *opaque KNOWN_UNUS
17
23
18
24
debug_printf (3 , "Trying to re-bind %s from tool %s after dlopen\n" ,
19
25
binding -> user_binding -> name , binding -> associated_binding_table -> tool -> tool_name );
20
-
26
+
21
27
while (binding -> next_binding ) {
22
28
binding = binding -> next_binding ;
23
29
debug_printf (3 , "Selecting new innermost version of binding %s from tool %s.\n" ,
24
30
binding -> user_binding -> name , binding -> associated_binding_table -> tool -> tool_name );
25
31
}
26
-
32
+
27
33
result = prepare_symbol (binding );
28
34
if (result == -1 ) {
29
35
debug_printf (3 , "Still could not prepare binding %s after dlopen\n" , binding -> user_binding -> name );
@@ -45,7 +51,7 @@ static void* dlopen_wrapper(const char* filename, int flags) {
45
51
46
52
debug_printf (2 , "Updating GOT entries for new dlopened libraries\n" );
47
53
update_all_library_gots (& function_hash_table );
48
-
54
+
49
55
return handle ;
50
56
}
51
57
@@ -55,13 +61,17 @@ static void* dlsym_wrapper(void* handle, const char* symbol_name){
55
61
int result ;
56
62
debug_printf (1 , "User called dlsym(%p, %s)\n" , handle , symbol_name );
57
63
58
- if (handle == RTLD_NEXT ){
59
- return _dl_sym (RTLD_NEXT , symbol_name ,__builtin_return_address (0 ));
60
- }
61
- if (handle == RTLD_DEFAULT ) {
62
- return _dl_sym (RTLD_DEFAULT , symbol_name ,__builtin_return_address (0 ));
64
+ if (handle == RTLD_DEFAULT || handle == RTLD_NEXT ) {
65
+ #if defined GOTCHA_DL_SYM_WORKAROUND
66
+ /* Workaround as _dl_sym isn't exported in glibc 2.34+ anymore.
67
+ This probably breaks dlsym() wrapping for RTLD_NEXT: need to
68
+ wait for real fix in Gotcha.
69
+ */
70
+ return orig_dlsym (handle , symbol_name );
71
+ #else
72
+ return _dl_sym (handle , symbol_name ,__builtin_return_address (0 ));
73
+ #endif
63
74
}
64
-
65
75
result = lookup_hashtable (& function_hash_table , (hash_key_t ) symbol_name , (hash_data_t * ) & binding );
66
76
if (result == -1 )
67
77
return orig_dlsym (handle , symbol_name );
@@ -72,7 +82,7 @@ static void* dlsym_wrapper(void* handle, const char* symbol_name){
72
82
struct gotcha_binding_t dl_binds [] = {
73
83
{"dlopen" , dlopen_wrapper , & orig_dlopen_handle },
74
84
{"dlsym" , dlsym_wrapper , & orig_dlsym_handle }
75
- };
85
+ };
76
86
void handle_libdl (){
77
87
gotcha_wrap (dl_binds , 2 , "gotcha" );
78
88
}
0 commit comments