Skip to content

Added glibc_wrap to provide Linux OS backwards compatibility #362

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion cmake/manifests/linux/install_manifest.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
/fpga-runtime-for-opencl/include/MMD/aocl_mmd_deprecated.h
/__w/fpga-runtime-for-opencl/fpga-runtime-for-opencl/glibc_wrap/libglibc_wrap.a
16 changes: 16 additions & 0 deletions glibc_wrap/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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()
30 changes: 30 additions & 0 deletions glibc_wrap/glibc_wrap.c
Original file line number Diff line number Diff line change
@@ -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 <linux/unistd.h>
#include <math.h>
#include <sys/syscall.h>
#include <unistd.h>

#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); }