diff --git a/CMakeLists.txt b/CMakeLists.txt index 29f10434..36955fb8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,11 @@ set(CPACK_PACKAGE_VERSION_PATCH "0") set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md") set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE") +if (NOT WIN32) + set(GLIBC_WRAP_FUNCTIONS + -Wl,--wrap=gettid + -Wl,--wrap=log2) +endif() # Enforce keeping the source directory clean by building in a separate # directory. This avoids unnecessary corner cases, e.g., copying files # from source to binary directory with identical relative paths. @@ -333,7 +338,10 @@ target_link_libraries(acl PRIVATE if(UNIX) # we need this flag to expose symbols, otherwise linking will fail with: # "relocation against protected symbol X can not be used when making a shared object" + add_subdirectory(glibc_wrap) set_target_properties(acl PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic") + target_include_directories(acl PRIVATE ${CMAKE_SOURCE_DIR}/glibc_wrap) + target_link_libraries(acl PRIVATE glibc_wrap) endif() set_property(TARGET acl PROPERTY PUBLIC_HEADER diff --git a/cmake/manifests/linux/install_manifest.txt b/cmake/manifests/linux/install_manifest.txt index 21e7c497..014b9915 100644 --- a/cmake/manifests/linux/install_manifest.txt +++ b/cmake/manifests/linux/install_manifest.txt @@ -36,4 +36,5 @@ /fpga-runtime-for-opencl/include/CL/opencl.h /fpga-runtime-for-opencl/include/CL/opencl.hpp /fpga-runtime-for-opencl/include/MMD/aocl_mmd.h -/fpga-runtime-for-opencl/include/MMD/aocl_mmd_deprecated.h \ No newline at end of file +/fpga-runtime-for-opencl/include/MMD/aocl_mmd_deprecated.h +/__w/fpga-runtime-for-opencl/fpga-runtime-for-opencl/glibc_wrap/libglibc_wrap.a \ No newline at end of file diff --git a/glibc_wrap/CMakeLists.txt b/glibc_wrap/CMakeLists.txt new file mode 100644 index 00000000..7d5774b5 --- /dev/null +++ b/glibc_wrap/CMakeLists.txt @@ -0,0 +1,16 @@ +if (NOT WIN32) + add_library(glibc_wrap STATIC glibc_wrap.c) + # Ensure position-independent code is generated + set_target_properties(glibc_wrap PROPERTIES POSITION_INDEPENDENT_CODE ON) + target_include_directories(glibc_wrap PRIVATE ${CMAKE_SOURCE_DIR}/src) + # Specify the wrapped functions on the interface link options. + # This causes libraries linking against this one to use the wrapped + # functions rather than those in a potentially too new glibc for + # our minimum supported OS. See glibc_wrap.c for details. + target_link_libraries(glibc_wrap INTERFACE ${GLIBC_WRAP_FUNCTIONS}) + + # Link the math library for debian-11-arm-dev + target_link_libraries(glibc_wrap INTERFACE m) + + install(TARGETS glibc_wrap DESTINATION ${CMAKE_SOURCE_DIR}/glibc_wrap) +endif() diff --git a/glibc_wrap/glibc_wrap.c b/glibc_wrap/glibc_wrap.c new file mode 100644 index 00000000..3027a8af --- /dev/null +++ b/glibc_wrap/glibc_wrap.c @@ -0,0 +1,30 @@ +// These functions are only called by our code when built on newer distros. We +// add '-Wl,--wrap={funcname}' to the link line which changes all calls to +// '{funcname}' to '__wrap_{funcname}' + +// For all the gritty details: +// https://www.win.tue.nl/~aeb/linux/misc/gcc-semibug.html +// https://stackoverflow.com/questions/4032373/linking-against-an-old-version-of-libc-to-provide-greater-application-coverage + +#include +#include +#include +#include + +#ifndef __arm__ +// Use GLIBC 2.2.5 versioning only if not on ARM +asm(".symver log2_glibc_225, log2@GLIBC_2.2.5"); +extern double log2_glibc_225(double num); +#endif + +double __wrap_log2(double num) { +#ifdef __arm__ + // If compiling for ARM, just call the system-native log2 function + return log2(num); +#else + // Call the GLIBC 2.2.5 version of log2 if not on ARM + return log2_glibc_225(num); +#endif +} + +pid_t __wrap_gettid(void) { return (pid_t)syscall(SYS_gettid); }