From c09a9ef086f7a92719f6b576e1a19c2637158344 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Thu, 18 Apr 2024 23:45:16 -0700 Subject: [PATCH 01/14] Fix for not wrapping different wrappee. In cases, like in OpenCL, the main library (OpenCL) acts as a wrapper for other implementations (libamdocl64.so). In this case both have same function names implemented. If we wrap OpenCL functions with gotcha which dynamically loads libamdocl64.so with same function name, we should not return a wrapper meant to intercept OpenCL. So we should check if the wrapper given to the caller of dlsym is for the same wrappee as requested by the caller. --- .gitignore | 4 ++++ src/gotcha_dl.c | 12 ++++++++++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index 888035d..d61cd2a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,7 @@ build tags **/tags +*.core +.cache +.idea +.vscode \ No newline at end of file diff --git a/src/gotcha_dl.c b/src/gotcha_dl.c index 16e55b5..92dc11e 100644 --- a/src/gotcha_dl.c +++ b/src/gotcha_dl.c @@ -157,7 +157,15 @@ 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 && + (val == NULL || binding->user_binding->function_handle == 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 +176,7 @@ static void *dlsym_wrapper(void *handle, const char *symbol_name) { } return NULL; } else { - return orig_dlsym(handle, symbol_name); + return val; } } From 1d510f29ad541027071a2dadb2485843e83540be Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 22 Apr 2024 09:18:02 -0700 Subject: [PATCH 02/14] Adding test case for dispatcher. --- test/CMakeLists.txt | 3 +- test/dispatcher/CMakeLists.txt | 8 ++++ test/dispatcher/libdispatcher.c | 69 +++++++++++++++++++++++++++++++++ test/dispatcher/libimpl.c | 37 ++++++++++++++++++ test/dispatcher/main.c | 64 ++++++++++++++++++++++++++++++ 5 files changed, 180 insertions(+), 1 deletion(-) create mode 100644 test/dispatcher/CMakeLists.txt create mode 100644 test/dispatcher/libdispatcher.c create mode 100644 test/dispatcher/libimpl.c create mode 100644 test/dispatcher/main.c diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 70ff615..f36a28f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -12,4 +12,5 @@ add_subdirectory(filter) add_subdirectory(wrap_main) #add_subdirectory(multi_agent_dlopen) add_subdirectory(symver) -add_subdirectory(function_ptr) \ No newline at end of file +add_subdirectory(function_ptr) +add_subdirectory(dispatcher) \ No newline at end of file diff --git a/test/dispatcher/CMakeLists.txt b/test/dispatcher/CMakeLists.txt new file mode 100644 index 0000000..0b6e0f1 --- /dev/null +++ b/test/dispatcher/CMakeLists.txt @@ -0,0 +1,8 @@ +add_library(impl SHARED libimpl.c) +add_library(dispatcher SHARED libdispatcher.c) +target_link_libraries(dispatcher -ldl -lpthread) +add_executable(test_dispatcher main.c) +target_link_libraries(test_dispatcher gotcha dispatcher) +gotcha_add_test(dispatcher_test test_dispatcher) +set_property(TEST dispatcher_test APPEND PROPERTY ENVIRONMENT "GOTCHA_DEBUG=3") +set_property(TEST dispatcher_test APPEND PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file diff --git a/test/dispatcher/libdispatcher.c b/test/dispatcher/libdispatcher.c new file mode 100644 index 0000000..f24aa5d --- /dev/null +++ b/test/dispatcher/libdispatcher.c @@ -0,0 +1,69 @@ +/* +This file is part of GOTCHA. For copyright information see the COPYRIGHT +file in the top level directory, or at +https://github.com/LLNL/gotcha/blob/master/COPYRIGHT +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License (as published by the Free +Software Foundation) version 2.1 dated February 1999. This program is +distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the terms and conditions of the GNU Lesser General Public License +for more details. You should have received a copy of the GNU Lesser General +Public License along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +int foo(void); +int bar(void); + +static void* impl_lib; +static int (*impl_foo)(void); +static int (*impl_bar)(void); + +static pthread_once_t init_once = PTHREAD_ONCE_INIT; +void dispatch_init(void) { + fprintf(stderr, "Ed dispatch_init()\n"); + + impl_lib = dlopen("libimpl.so", RTLD_NOW); + impl_foo = dlsym(impl_lib, "foo"); + impl_bar = dlsym(impl_lib, "bar"); + + int ret = impl_bar(); + + fprintf(stderr, "Ld dispatch_init() = %d\n", ret); +} + +int foo(void) { + fprintf(stderr, "Ed foo()\n"); + + pthread_once(&init_once, dispatch_init); + + int ret = impl_bar() + impl_foo(); + + fprintf(stderr, "Ld foo()\n"); + + return ret; +} + +int bar(void) { + fprintf(stderr, "Ed bar()\n"); + + pthread_once(&init_once, dispatch_init); + + int ret = impl_bar(); + + fprintf(stderr, "Ld bar()\n"); + + return ret; +} diff --git a/test/dispatcher/libimpl.c b/test/dispatcher/libimpl.c new file mode 100644 index 0000000..517e3f8 --- /dev/null +++ b/test/dispatcher/libimpl.c @@ -0,0 +1,37 @@ +/* +This file is part of GOTCHA. For copyright information see the COPYRIGHT +file in the top level directory, or at +https://github.com/LLNL/gotcha/blob/master/COPYRIGHT +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License (as published by the Free +Software Foundation) version 2.1 dated February 1999. This program is +distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the terms and conditions of the GNU Lesser General Public License +for more details. You should have received a copy of the GNU Lesser General +Public License along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int foo(void) { + fprintf(stderr, "Ei foo()\n"); + fprintf(stderr, "Li foo()\n"); + + return 42; +} + +int bar(void) { + fprintf(stderr, "Ei bar()\n"); + fprintf(stderr, "Li bar()\n"); + + return 23; +} diff --git a/test/dispatcher/main.c b/test/dispatcher/main.c new file mode 100644 index 0000000..bb7eb84 --- /dev/null +++ b/test/dispatcher/main.c @@ -0,0 +1,64 @@ +/* +This file is part of GOTCHA. For copyright information see the COPYRIGHT +file in the top level directory, or at +https://github.com/LLNL/gotcha/blob/master/COPYRIGHT +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License (as published by the Free +Software Foundation) version 2.1 dated February 1999. This program is +distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; +without even the IMPLIED WARRANTY OF MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the terms and conditions of the GNU Lesser General Public License +for more details. You should have received a copy of the GNU Lesser General +Public License along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include + +int foo(void); +int bar(void); +#include + +static gotcha_wrappee_handle_t handle_foo; +static gotcha_wrappee_handle_t handle_bar; + +static int do_foo(void) { + fprintf(stderr, "Ew foo()\n"); + + typeof(&do_foo) orig_foo = gotcha_get_wrappee(handle_foo); + int ret = orig_foo(); + + fprintf(stderr, "Lw foo() = %d\n", ret); + + return ret; +} + +static int do_bar(void) { + fprintf(stderr, "Ew bar()\n"); + + typeof(&do_bar) orig_bar = gotcha_get_wrappee(handle_bar); + int ret = orig_bar(); + + fprintf(stderr, "Lw bar() = %d\n", ret); + + return ret; +} + +static struct gotcha_binding_t bindings[] = { + {"foo", do_foo, &handle_foo}, + {"bar", do_bar, &handle_bar}, +}; + +int main(int ac, char *av[]) { + gotcha_wrap(bindings, 2, "test"); + printf("%d\n", foo()); + + return 0; +} From 4c469e4804a39cb43d56db16e2b006b31ef3b25d Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 22 Apr 2024 13:26:41 -0700 Subject: [PATCH 03/14] Cleanup for PR --- .gitignore | 2 +- test/CMakeLists.txt | 2 +- test/dispatcher/CMakeLists.txt | 2 +- test/dispatcher/libdispatcher.c | 10 ++++------ test/dispatcher/libimpl.c | 6 ------ test/dispatcher/main.c | 8 +------- 6 files changed, 8 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index d61cd2a..2350365 100644 --- a/.gitignore +++ b/.gitignore @@ -7,4 +7,4 @@ tags *.core .cache .idea -.vscode \ No newline at end of file +.vscode diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index f36a28f..80bb07f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -13,4 +13,4 @@ add_subdirectory(wrap_main) #add_subdirectory(multi_agent_dlopen) add_subdirectory(symver) add_subdirectory(function_ptr) -add_subdirectory(dispatcher) \ No newline at end of file +add_subdirectory(dispatcher) diff --git a/test/dispatcher/CMakeLists.txt b/test/dispatcher/CMakeLists.txt index 0b6e0f1..17fa6ae 100644 --- a/test/dispatcher/CMakeLists.txt +++ b/test/dispatcher/CMakeLists.txt @@ -5,4 +5,4 @@ add_executable(test_dispatcher main.c) target_link_libraries(test_dispatcher gotcha dispatcher) gotcha_add_test(dispatcher_test test_dispatcher) set_property(TEST dispatcher_test APPEND PROPERTY ENVIRONMENT "GOTCHA_DEBUG=3") -set_property(TEST dispatcher_test APPEND PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}") \ No newline at end of file +set_property(TEST dispatcher_test APPEND PROPERTY ENVIRONMENT "LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}") diff --git a/test/dispatcher/libdispatcher.c b/test/dispatcher/libdispatcher.c index f24aa5d..9c16ddb 100644 --- a/test/dispatcher/libdispatcher.c +++ b/test/dispatcher/libdispatcher.c @@ -14,15 +14,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE +#include #include -#include #include -#include -#include #include -#include -#include -#include int foo(void); int bar(void); @@ -36,8 +31,11 @@ void dispatch_init(void) { fprintf(stderr, "Ed dispatch_init()\n"); impl_lib = dlopen("libimpl.so", RTLD_NOW); + assert(impl_lib); impl_foo = dlsym(impl_lib, "foo"); + assert(impl_foo); impl_bar = dlsym(impl_lib, "bar"); + assert(impl_bar); int ret = impl_bar(); diff --git a/test/dispatcher/libimpl.c b/test/dispatcher/libimpl.c index 517e3f8..5318df7 100644 --- a/test/dispatcher/libimpl.c +++ b/test/dispatcher/libimpl.c @@ -14,13 +14,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE -#include -#include -#include #include -#include -#include -#include int foo(void) { fprintf(stderr, "Ei foo()\n"); diff --git a/test/dispatcher/main.c b/test/dispatcher/main.c index bb7eb84..cc44ddb 100644 --- a/test/dispatcher/main.c +++ b/test/dispatcher/main.c @@ -14,17 +14,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #define _GNU_SOURCE -#include -#include -#include +#include #include -#include -#include -#include int foo(void); int bar(void); -#include static gotcha_wrappee_handle_t handle_foo; static gotcha_wrappee_handle_t handle_bar; From 0d838a9e7b0471e5314bcf5c8a524a171b956c69 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 29 Apr 2024 11:10:19 -0700 Subject: [PATCH 04/14] get the correct wrappee from function handle. This is required to ensure we only wrap functions that are available at the time of wrapping. --- src/gotcha.c | 2 +- src/gotcha_dl.c | 5 +-- src/gotcha_dl.h | 1 + test/dlopen/num.c | 1 - test/dlopen/num2.c | 10 +++--- test/dlopen/test_dlopen.c | 74 +++++++++++++++++++++++++++------------ 6 files changed, 62 insertions(+), 31 deletions(-) diff --git a/src/gotcha.c b/src/gotcha.c index 480c181..3d9db45 100644 --- a/src/gotcha.c +++ b/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/src/gotcha_dl.c b/src/gotcha_dl.c index 92dc11e..e54f506 100644 --- a/src/gotcha_dl.c +++ b/src/gotcha_dl.c @@ -158,8 +158,9 @@ static void *dlsym_wrapper(void *handle, const char *symbol_name) { int result = lookup_hashtable(&function_hash_table, (hash_key_t)symbol_name, (hash_data_t *)&binding); void *val = orig_dlsym(handle, symbol_name); - if (result != -1 && - (val == NULL || binding->user_binding->function_handle == val)) { + void **wrappee_ptr = getInternalBindingAddressPointer( + (struct internal_binding_t **)binding->user_binding->function_handle); + if (result != -1 && (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 diff --git a/src/gotcha_dl.h b/src/gotcha_dl.h index f968e92..252f5ae 100644 --- a/src/gotcha_dl.h +++ b/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; diff --git a/test/dlopen/num.c b/test/dlopen/num.c index b7a6be5..171619c 100644 --- a/test/dlopen/num.c +++ b/test/dlopen/num.c @@ -13,7 +13,6 @@ Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -extern void mark_had_error(); extern int return_five(); int return_four() { diff --git a/test/dlopen/num2.c b/test/dlopen/num2.c index 7375182..4c5e567 100644 --- a/test/dlopen/num2.c +++ b/test/dlopen/num2.c @@ -13,9 +13,9 @@ Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -extern void mark_had_error(); -extern int return_five(); +int return_four() { return 6; } -int return_four() { return 4; } - -int test_return_five() { return return_five(); } +int return_six() { + /* Intentional bug, gotcha wrapping will correct this to return 6 */ + return 7; +} diff --git a/test/dlopen/test_dlopen.c b/test/dlopen/test_dlopen.c index 88b8c35..e47a583 100644 --- a/test/dlopen/test_dlopen.c +++ b/test/dlopen/test_dlopen.c @@ -32,51 +32,52 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #define LIB_NAME QUOTE(LIB_NAME_RAW) #define LIB2_NAME QUOTE(LIB2_NAME_RAW) int correct_return_four() { return 4; } +int correct_return_five() { return 5; } +int correct_return_six() { return 6; } int return_five() { /* Intentional bug, gotcha will correct this to return 5*/ return 3; } -int correct_return_five() { return 5; } - static gotcha_wrappee_handle_t buggy_return_four; static gotcha_wrappee_handle_t buggy_return_five; +static gotcha_wrappee_handle_t buggy_return_six; + struct gotcha_binding_t funcs[] = { {"return_four", correct_return_four, &buggy_return_four}, - {"return_five", correct_return_five, &buggy_return_five}}; + {"return_five", correct_return_five, &buggy_return_five}, + {"return_six", correct_return_six, &buggy_return_six}}; int main() { void *libnum; + void *libnum2; int (*retfour)(void); + int (*retsix)(void); int (*test_retfive)(void); int (*retdummy)(void); int had_error = 0; int result; - - result = gotcha_wrap(funcs, 2, "dlopen_test"); + /* We wrap the functions before they are loaded */ + result = gotcha_wrap(funcs, 3, "dlopen_test"); if (result != GOTCHA_FUNCTION_NOT_FOUND) { fprintf(stderr, "GOTCHA should have failed to find a function, but found it\n"); return -1; } - + /* Load the first libnum.so */ libnum = dlopen(LIB_NAME, RTLD_NOW); if (!libnum) { fprintf(stderr, "ERROR: Test failed to dlopen libnum.so\n"); return -1; } - libnum = dlopen(LIB2_NAME, RTLD_NOW); - if (!libnum) { - fprintf(stderr, "ERROR: Test failed to dlopen libnum2.so\n"); - return -1; - } - /* Test 1: Check if a dlsym generated indirect call gets re-routed by gotcha - */ + /* Check if return_four is wrapped from libnum.so */ retfour = (int (*)(void))dlsym(libnum, "return_four"); - if (retfour() != 4) { - fprintf(stderr, "ERROR: dlsym returned original function, not wrapped\n"); + if (retfour == NULL || retfour() != 4) { + fprintf(stderr, + "ERROR: dlsym returned original function, not wrapped from " + "libnum.so\n"); had_error = -1; } @@ -88,16 +89,25 @@ int main() { "by correct_return_five\n"); had_error = -1; } - /* Test 3: Does the dlsym implementation find the second occurrence of the - * symbol */ - test_retfive = (int (*)(void))dlsym(RTLD_NEXT, "test_return_five"); - if (test_retfive == NULL || test_retfive() != 5) { + + /* Load libnum2.so */ + libnum2 = dlopen(LIB2_NAME, RTLD_NOW); + if (!libnum) { + fprintf(stderr, "ERROR: Test failed to dlopen libnum2.so\n"); + return -1; + } + + /* Check if return_six is wrapped from libnum2.so */ + retsix = (int (*)(void))dlsym(libnum2, "return_six"); + if (retsix == NULL || retsix() != 6) { fprintf(stderr, - "ERROR: call to return_four should not be found in " - "RTLD_NEXT from libnum2.so and return 4\n"); + "ERROR: dlsym returned original function, not wrapped from " + "libnum2.so\n"); had_error = -1; } - /* Test 4: Does the dlsym implementation find the first occurrence of the + + /* Check RTLD_DEFAULT */ + /* Does the dlsym implementation find the first occurrence of the * symbol */ retfour = (int (*)(void))dlsym(RTLD_DEFAULT, "return_four"); if (retfour == NULL || retfour() != 4) { @@ -113,6 +123,15 @@ int main() { "by correct_return_five\n"); had_error = -1; } + + retsix = (int (*)(void))dlsym(RTLD_DEFAULT, "return_six"); + if (retsix == NULL || retsix() != 6) { + fprintf(stderr, + "ERROR: call to return_five in libnum2.so was not wrapped " + "by correct_return_five\n"); + had_error = -1; + } + retdummy = (int (*)(void))dlsym(RTLD_DEFAULT, "return_dummy"); if (retdummy != NULL) { fprintf( @@ -120,6 +139,17 @@ int main() { "ERROR: call to return_dummy should not be found in RTLD_DEFAULT\n"); had_error = -1; } + + /* Test RTLD_NEXT */ + /* Does the dlsym implementation find the second occurrence of the + * symbol */ + test_retfive = (int (*)(void))dlsym(RTLD_NEXT, "test_return_five"); + if (test_retfive == NULL || test_retfive() != 5) { + fprintf(stderr, + "ERROR: call to return_four should not be found in " + "RTLD_NEXT from libnum2.so and return 4\n"); + had_error = -1; + } retdummy = (int (*)(void))dlsym(RTLD_NEXT, "return_dummy"); if (retdummy != NULL) { fprintf(stderr, From 5766fdf80a581396795cb4f0a587969fcc19b0d7 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 29 Apr 2024 15:57:58 -0700 Subject: [PATCH 05/14] added code for version macro for code to check. --- CMakeLists.txt | 12 ++++++++++++ cmake/gotcha_config.h.in | 9 +++++++++ include/gotcha/gotcha.h | 4 ++-- 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 cmake/gotcha_config.h.in diff --git a/CMakeLists.txt b/CMakeLists.txt index aaba856..5a90b72 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,6 +10,10 @@ set(LIBTOOL_INTERFACE 2) set(LIBTOOL_REVISION 3) set(LIBTOOL_AGE 2) +set(GOTCHA_VERSION_MAJOR 1) +set(GOTCHA_VERSION_MINOR 0) +set(GOTCHA_VERSION_PATCH 6) + set(DEFAULT_SYMBOL_VISIBILITY hidden) if(GOTCHA_ENABLE_TESTS) @@ -22,6 +26,7 @@ if(GOTCHA_ENABLE_TESTS) endif() endif() include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include) +include_directories(${CMAKE_BINARY_DIR}/include) add_subdirectory(include) add_subdirectory(src) if(GOTCHA_ENABLE_TESTS) @@ -50,3 +55,10 @@ configure_package_config_file( install( FILES "${CMAKE_CURRENT_BINARY_DIR}/gotcha-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/gotcha-config-version.cmake" DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/gotcha") + +# Write the configure file +configure_file("${CMAKE_SOURCE_DIR}/cmake/gotcha_config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/include/gotcha/gotcha_config.h" @ONLY) +install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/include/gotcha/gotcha_config.h" + DESTINATION "${gotcha_INSTALL_INCLUDE_DIR}/gotcha/gotcha_config.h") \ No newline at end of file diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in new file mode 100644 index 0000000..9495d7c --- /dev/null +++ b/cmake/gotcha_config.h.in @@ -0,0 +1,9 @@ +#ifndef GOTCHA_CONFIG_HPP +#define GOTCHA_CONFIG_HPP + +#define GOTCHA_VERSION_MAJOR "@GOTCHA_VERSION_MAJOR@" +#define GOTCHA_VERSION_MINOR "@GOTCHA_VERSION_MINOR@" +#define GOTCHA_VERSION_PATCH "@GOTCHA_VERSION_PATCH@" +#define GOTCHA_VERSION "@GOTCHA_VERSION_MAJOR@.@GOTCHA_VERSION_MINOR@.@GOTCHA_VERSION_PATCH@" + +#endif /* HPC_AIO_CONFIG_H */ diff --git a/include/gotcha/gotcha.h b/include/gotcha/gotcha.h index f46fec0..1180245 100644 --- a/include/gotcha/gotcha.h +++ b/include/gotcha/gotcha.h @@ -30,10 +30,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA #ifndef GOTCHA_H #define GOTCHA_H +#include +#include #include -#include "gotcha/gotcha_types.h" - #if defined(__cplusplus) extern "C" { #endif From ffd9d6df60d972299238d7271b9e05d0e82add14 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 29 Apr 2024 15:59:58 -0700 Subject: [PATCH 06/14] Added new line --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5a90b72..1d63887 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -61,4 +61,4 @@ configure_file("${CMAKE_SOURCE_DIR}/cmake/gotcha_config.h.in" "${CMAKE_CURRENT_BINARY_DIR}/include/gotcha/gotcha_config.h" @ONLY) install( FILES "${CMAKE_CURRENT_BINARY_DIR}/include/gotcha/gotcha_config.h" - DESTINATION "${gotcha_INSTALL_INCLUDE_DIR}/gotcha/gotcha_config.h") \ No newline at end of file + DESTINATION "${gotcha_INSTALL_INCLUDE_DIR}/gotcha/gotcha_config.h") From 2da5082f3d6a992005d98dcfa7f8946b6c7bc15c Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 29 Apr 2024 18:57:41 -0700 Subject: [PATCH 07/14] improved the macro for better comparisions --- CMakeLists.txt | 6 +++--- cmake/gotcha_config.h.in | 8 ++++---- docs/api.rst | 22 ++++++++++++++++++++++ 3 files changed, 29 insertions(+), 7 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d63887..f4d9772 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,9 +10,9 @@ set(LIBTOOL_INTERFACE 2) set(LIBTOOL_REVISION 3) set(LIBTOOL_AGE 2) -set(GOTCHA_VERSION_MAJOR 1) -set(GOTCHA_VERSION_MINOR 0) -set(GOTCHA_VERSION_PATCH 6) +# VERSION is XYYYZZ X: Major Y Minor Z PATCH +set(GOTCHA_VERSION 100006) + set(DEFAULT_SYMBOL_VISIBILITY hidden) diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in index 9495d7c..3052f5f 100644 --- a/cmake/gotcha_config.h.in +++ b/cmake/gotcha_config.h.in @@ -1,9 +1,9 @@ #ifndef GOTCHA_CONFIG_HPP #define GOTCHA_CONFIG_HPP -#define GOTCHA_VERSION_MAJOR "@GOTCHA_VERSION_MAJOR@" -#define GOTCHA_VERSION_MINOR "@GOTCHA_VERSION_MINOR@" -#define GOTCHA_VERSION_PATCH "@GOTCHA_VERSION_PATCH@" -#define GOTCHA_VERSION "@GOTCHA_VERSION_MAJOR@.@GOTCHA_VERSION_MINOR@.@GOTCHA_VERSION_PATCH@" +#define GOTCHA_VERSION @GOTCHA_VERSION@ +#define GOTCHA_VERSION_MAJOR (GOTCHA_VERSION / 100000) +#define GOTCHA_VERSION_MINOR ((GOTCHA_VERSION / 100) % 1000) +#define GOTCHA_VERSION_PATCH (GOTCHA_VERSION % 100) #endif /* HPC_AIO_CONFIG_H */ diff --git a/docs/api.rst b/docs/api.rst index 0f76c40..b9cddef 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -178,5 +178,27 @@ The default filter of gotcha selects all libraries loaded. This function set the .. explicit external hyperlink targets +--------------------------- +Using Gotcha Version Macros +--------------------------- + +The source version of GOTCHA is defined by the `GOTCHA_VERSION` macro which uses the XYYYZZ format. +Here, X signifies the major version, Y is the minor version, and Z is the patch. +Additionally, we define `GOTCHA_VERSION_MAJOR`, `GOTCHA_VERSION_MINOR`, and `GOTCHA_VERSION_PATCH` macros for convienience. +The codes can use the macros like + + +.. code-block:: c + + #if GOTCHA_VERSION > 100006 // this will check of version greater than 1.0.6 + #endif + + #if GOTCHA_VERSION_MAJOR > 1 // this will check of version greater than 2.0.0 + #endif + + + + + .. _`gnu constructor`: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html .. _symbol: https://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-PDA/LSB-PDA.junk/symversion.html From b1bcd16fb8c456cc60f6a2005fc5b360b34ed288 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 29 Apr 2024 21:44:29 -0700 Subject: [PATCH 08/14] added a convienience macro to get version --- cmake/gotcha_config.h.in | 1 + docs/api.rst | 2 ++ 2 files changed, 3 insertions(+) diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in index 3052f5f..d69d271 100644 --- a/cmake/gotcha_config.h.in +++ b/cmake/gotcha_config.h.in @@ -5,5 +5,6 @@ #define GOTCHA_VERSION_MAJOR (GOTCHA_VERSION / 100000) #define GOTCHA_VERSION_MINOR ((GOTCHA_VERSION / 100) % 1000) #define GOTCHA_VERSION_PATCH (GOTCHA_VERSION % 100) +#define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) MAJOR * 100000 + MINOR * 100 + PATCH #endif /* HPC_AIO_CONFIG_H */ diff --git a/docs/api.rst b/docs/api.rst index b9cddef..db0479d 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -196,6 +196,8 @@ The codes can use the macros like #if GOTCHA_VERSION_MAJOR > 1 // this will check of version greater than 2.0.0 #endif + #if GOTCHA_VERSION > GOTCHA_GET_VERSION(1,0,6) // this will check of version greater than 1.0.6 + #endif From 5a25fffe1e52290019b656765044d8a9eac8779c Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 20 May 2024 09:18:01 -0700 Subject: [PATCH 09/14] fixes for macros. --- CMakeLists.txt | 2 +- cmake/gotcha_config.h.in | 10 +++++----- docs/api.rst | 1 + 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index f4d9772..87f5201 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,7 +11,7 @@ set(LIBTOOL_REVISION 3) set(LIBTOOL_AGE 2) # VERSION is XYYYZZ X: Major Y Minor Z PATCH -set(GOTCHA_VERSION 100006) +set(GOTCHA_VERSION "(1, 0, 6)") set(DEFAULT_SYMBOL_VISIBILITY hidden) diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in index d69d271..7b8538c 100644 --- a/cmake/gotcha_config.h.in +++ b/cmake/gotcha_config.h.in @@ -1,10 +1,10 @@ -#ifndef GOTCHA_CONFIG_HPP -#define GOTCHA_CONFIG_HPP +#ifndef GOTCHA_CONFIG_H +#define GOTCHA_CONFIG_H -#define GOTCHA_VERSION @GOTCHA_VERSION@ +#define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) MAJOR * 100000 + MINOR * 100 + PATCH +#define GOTCHA_VERSION GOTCHA_GET_VERSION @GOTCHA_VERSION@ #define GOTCHA_VERSION_MAJOR (GOTCHA_VERSION / 100000) #define GOTCHA_VERSION_MINOR ((GOTCHA_VERSION / 100) % 1000) #define GOTCHA_VERSION_PATCH (GOTCHA_VERSION % 100) -#define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) MAJOR * 100000 + MINOR * 100 + PATCH -#endif /* HPC_AIO_CONFIG_H */ +#endif /* GOTCHA_CONFIG_H */ diff --git a/docs/api.rst b/docs/api.rst index db0479d..a67392b 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -183,6 +183,7 @@ Using Gotcha Version Macros --------------------------- The source version of GOTCHA is defined by the `GOTCHA_VERSION` macro which uses the XYYYZZ format. +**Available since version 1.0.7.** Here, X signifies the major version, Y is the minor version, and Z is the patch. Additionally, we define `GOTCHA_VERSION_MAJOR`, `GOTCHA_VERSION_MINOR`, and `GOTCHA_VERSION_PATCH` macros for convienience. The codes can use the macros like From 1e592ba4b95e344f28c77c5ec757127ed2980a5d Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 20 May 2024 09:18:47 -0700 Subject: [PATCH 10/14] removed comments --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 87f5201..d0591a3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,6 @@ set(LIBTOOL_INTERFACE 2) set(LIBTOOL_REVISION 3) set(LIBTOOL_AGE 2) -# VERSION is XYYYZZ X: Major Y Minor Z PATCH set(GOTCHA_VERSION "(1, 0, 6)") From cef7dd5a1b12c83f86327a14c3876fd0b2edd93d Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 20 May 2024 09:32:37 -0700 Subject: [PATCH 11/14] added test cases. --- cmake/gotcha_config.h.in | 2 +- test/unit/gotcha_unit_tests.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in index 7b8538c..eed2e5b 100644 --- a/cmake/gotcha_config.h.in +++ b/cmake/gotcha_config.h.in @@ -2,7 +2,7 @@ #define GOTCHA_CONFIG_H #define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) MAJOR * 100000 + MINOR * 100 + PATCH -#define GOTCHA_VERSION GOTCHA_GET_VERSION @GOTCHA_VERSION@ +#define GOTCHA_VERSION (GOTCHA_GET_VERSION @GOTCHA_VERSION@) #define GOTCHA_VERSION_MAJOR (GOTCHA_VERSION / 100000) #define GOTCHA_VERSION_MINOR ((GOTCHA_VERSION / 100) % 1000) #define GOTCHA_VERSION_PATCH (GOTCHA_VERSION % 100) diff --git a/test/unit/gotcha_unit_tests.c b/test/unit/gotcha_unit_tests.c index 3a0c36e..e963955 100644 --- a/test/unit/gotcha_unit_tests.c +++ b/test/unit/gotcha_unit_tests.c @@ -558,6 +558,22 @@ Suite *gotcha_hash_suite() { return s; } +START_TEST(gotcha_version_check) { + ck_assert_msg(GOTCHA_GET_VERSION(1, 0, 3) > GOTCHA_GET_VERSION(1, 0, 2), + "Check GOTCHA_GET_VERSION failed"); + ck_assert_msg(GOTCHA_VERSION >= GOTCHA_GET_VERSION(1, 0, 6), + "Check GOTCHA_VERSION failed"); +} +END_TEST + +Suite *gotcha_version_suite() { + Suite *s = suite_create("Gotcha Version"); + TCase *version_case = configured_case_create("Basic tests"); + tcase_add_test(version_case, gotcha_version_check); + suite_add_tcase(s, version_case); + return s; +} + ////////////Launch///Tests//////////// int main() { @@ -578,9 +594,14 @@ int main() { SRunner *hash_runner = srunner_create(hash_suite); srunner_run_all(hash_runner, CK_NORMAL); num_fails += srunner_ntests_failed(hash_runner); + Suite *version_suite = gotcha_version_suite(); + SRunner *version_runner = srunner_create(version_suite); + srunner_run_all(version_runner, CK_NORMAL); + num_fails += srunner_ntests_failed(version_runner); srunner_free(core_runner); srunner_free(libc_runner); srunner_free(auxv_runner); srunner_free(hash_runner); + srunner_free(version_runner); return num_fails; } From 50dabb26a121a8b90842f6f6e440340266076f64 Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Tue, 28 May 2024 19:19:41 -0700 Subject: [PATCH 12/14] added a null check as we should not find null entries. --- src/gotcha_dl.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/gotcha_dl.c b/src/gotcha_dl.c index 16e55b5..91e7020 100644 --- a/src/gotcha_dl.c +++ b/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, From e02e987e878f9414ecdf8d52df1cef40205c2fa9 Mon Sep 17 00:00:00 2001 From: Hariharan Devarajan Date: Wed, 29 May 2024 21:58:02 -0700 Subject: [PATCH 13/14] Update gotcha_config.h.in --- cmake/gotcha_config.h.in | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/gotcha_config.h.in b/cmake/gotcha_config.h.in index eed2e5b..14a4a4d 100644 --- a/cmake/gotcha_config.h.in +++ b/cmake/gotcha_config.h.in @@ -1,7 +1,7 @@ #ifndef GOTCHA_CONFIG_H #define GOTCHA_CONFIG_H -#define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) MAJOR * 100000 + MINOR * 100 + PATCH +#define GOTCHA_GET_VERSION(MAJOR, MINOR, PATCH) (MAJOR * 100000 + MINOR * 100 + PATCH) #define GOTCHA_VERSION (GOTCHA_GET_VERSION @GOTCHA_VERSION@) #define GOTCHA_VERSION_MAJOR (GOTCHA_VERSION / 100000) #define GOTCHA_VERSION_MINOR ((GOTCHA_VERSION / 100) % 1000) From 7578aa45be67b3e6a6c237edd049fc76a701a0cf Mon Sep 17 00:00:00 2001 From: hariharandev1 Date: Mon, 17 Jun 2024 15:35:17 -0700 Subject: [PATCH 14/14] Changes for release 1.0.7 --- CMakeLists.txt | 2 +- README.md | 2 +- docs/conf.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d0591a3..1103b0c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ set(LIBTOOL_INTERFACE 2) set(LIBTOOL_REVISION 3) set(LIBTOOL_AGE 2) -set(GOTCHA_VERSION "(1, 0, 6)") +set(GOTCHA_VERSION "(1, 0, 7)") set(DEFAULT_SYMBOL_VISIBILITY hidden) diff --git a/README.md b/README.md index bf85e7c..07f966e 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -GOTCHA v1.0.6 +GOTCHA v1.0.7 ============ [![GOTCHA Build and Test](https://github.com/LLNL/GOTCHA/actions/workflows/build-and-test.yaml/badge.svg)](https://github.com/LLNL/GOTCHA/actions/workflows/build-and-test.yaml) [![Coverage Status](https://coveralls.io/repos/github/LLNL/GOTCHA/badge.svg?branch=develop)](https://coveralls.io/github/LLNL/GOTCHA?branch=develop) diff --git a/docs/conf.py b/docs/conf.py index fe8ce87..57a02b6 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -26,7 +26,7 @@ # The short X.Y version version = u'1.0' # The full version, including alpha/beta/rc tags -release = u'1.0.6' +release = u'1.0.7' # -- General configuration ---------------------------------------------------