diff --git a/ext/gotcha/include/gotcha/gotcha.h b/ext/gotcha/include/gotcha/gotcha.h index f46fec042..7f3a77d29 100644 --- a/ext/gotcha/include/gotcha/gotcha.h +++ b/ext/gotcha/include/gotcha/gotcha.h @@ -30,10 +30,12 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #ifndef GOTCHA_H #define GOTCHA_H +/* Only contains the GOTCHA version, not needed for our Caliper copy +#include +*/ +#include #include -#include "gotcha/gotcha_types.h" - #if defined(__cplusplus) extern "C" { #endif diff --git a/ext/gotcha/src/gotcha.c b/ext/gotcha/src/gotcha.c index 480c1819f..3d9db4561 100644 --- a/ext/gotcha/src/gotcha.c +++ b/ext/gotcha/src/gotcha.c @@ -40,7 +40,7 @@ static void setBindingAddressPointer(struct gotcha_binding_t *in, void *value) { writeAddress(target, value); } -static void **getInternalBindingAddressPointer(struct internal_binding_t **in) { +void **getInternalBindingAddressPointer(struct internal_binding_t **in) { return (void **)&((*in)->wrappee_pointer); } diff --git a/ext/gotcha/src/gotcha_dl.c b/ext/gotcha/src/gotcha_dl.c index 16e55b579..fe9308d6c 100644 --- a/ext/gotcha/src/gotcha_dl.c +++ b/ext/gotcha/src/gotcha_dl.c @@ -113,6 +113,7 @@ static int per_binding(hash_key_t key, hash_data_t data, binding->user_binding->name, binding->associated_binding_table->tool->tool_name); + if (!binding->user_binding->name) return 0; while (binding->next_binding) { binding = binding->next_binding; // GCOVR_EXCL_START debug_printf(3, @@ -157,7 +158,18 @@ static void *dlsym_wrapper(void *handle, const char *symbol_name) { debug_printf(1, "User called dlsym(%p, %s)\n", handle, symbol_name); int result = lookup_hashtable(&function_hash_table, (hash_key_t)symbol_name, (hash_data_t *)&binding); - if (result != -1) return binding->user_binding->wrapper_pointer; + void *val = orig_dlsym(handle, symbol_name); + if (result != -1) { + void **wrappee_ptr = getInternalBindingAddressPointer( + (struct internal_binding_t **)binding->user_binding->function_handle); + if (val == NULL || *wrappee_ptr == val) { + // if the wrapper is found and the wrappee is the function requested. + // This is needed in cases where we wrap a function F1 from library A and + // we dynamically load function F1 from library B. As name is same, we + // need to make sure the wrappee are the same as well + return binding->user_binding->wrapper_pointer; + } + } if (handle == RTLD_NEXT) { struct link_map *lib = gotchas_dlsym_rtld_next_lookup( symbol_name, __builtin_return_address(0)); @@ -168,7 +180,7 @@ static void *dlsym_wrapper(void *handle, const char *symbol_name) { } return NULL; } else { - return orig_dlsym(handle, symbol_name); + return val; } } diff --git a/ext/gotcha/src/gotcha_dl.h b/ext/gotcha/src/gotcha_dl.h index f968e92ff..252f5ae10 100644 --- a/ext/gotcha/src/gotcha_dl.h +++ b/ext/gotcha/src/gotcha_dl.h @@ -9,6 +9,7 @@ extern void update_all_library_gots(hash_table_t *bindings); extern long lookup_exported_symbol(const char *name, const struct link_map *lib, void **symbol); extern int prepare_symbol(struct internal_binding_t *binding); +extern void **getInternalBindingAddressPointer(struct internal_binding_t **in); extern gotcha_wrappee_handle_t orig_dlopen_handle; extern gotcha_wrappee_handle_t orig_dlsym_handle;