Skip to content

Commit

Permalink
Use GCC visibility attributes on Unix (#1114)
Browse files Browse the repository at this point in the history
* To allow compiling with -fvisibility=hidden flag, GCC visibility attributes (with value "default") should be set.
* Enforce exporting unsafe_wait symbols on MacOS

Signed-off-by: Vladislav Shchapov <vladislav@shchapov.ru>
  • Loading branch information
phprus authored Sep 24, 2024
1 parent c881143 commit 4b02f62
Show file tree
Hide file tree
Showing 13 changed files with 101 additions and 67 deletions.
11 changes: 11 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ cmake_minimum_required(VERSION 3.5)

# Enable CMake policies

if (POLICY CMP0063)
# The NEW behavior for this policy is to honor the visibility properties for all target types.
cmake_policy(SET CMP0063 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0063 NEW)
endif()

if (POLICY CMP0068)
# RPATH settings do not affect install_name on macOS since CMake 3.9
cmake_policy(SET CMP0068 NEW)
Expand Down Expand Up @@ -84,6 +90,11 @@ endif()

set(CMAKE_CXX_EXTENSIONS OFF) # use -std=c++... instead of -std=gnu++...
# ---------------------------------------------------------------------------------------------------------
# Setup symbol visibility properties.

set(CMAKE_VISIBILITY_INLINES_HIDDEN TRUE)
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
# ---------------------------------------------------------------------------------------------------------

# Detect architecture (bitness).
if (CMAKE_SIZEOF_VOID_P EQUAL 4)
Expand Down
8 changes: 7 additions & 1 deletion include/oneapi/tbb/detail/_exception.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -66,10 +66,16 @@ class TBB_EXPORT missing_wait : public std::exception {
};

//! Exception for impossible finalization of task_sheduler_handle
#if __APPLE__
#pragma GCC visibility push(default)
#endif
class TBB_EXPORT unsafe_wait : public std::runtime_error {
public:
unsafe_wait(const char* msg) : std::runtime_error(msg) {}
};
#if __APPLE__
#pragma GCC visibility pop
#endif

//! Gathers all throw operators in one place.
/** Its purpose is to minimize code bloat that can be caused by throw operators
Expand Down
22 changes: 15 additions & 7 deletions include/oneapi/tbb/detail/_export.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -18,27 +18,35 @@
#define __TBB_detail__export_H

#if defined(__MINGW32__)
#define _EXPORT __declspec(dllexport)
#elif defined(_WIN32) || defined(__unix__) || defined(__APPLE__) // Use .def files for these
#define _EXPORT
#define __TBB_EXPORT __declspec(dllexport)
#elif defined(_WIN32) // Use .def files for these
#define __TBB_EXPORT
#elif defined(__unix__) || defined(__APPLE__) // Use .def files for these
#define __TBB_EXPORT __attribute__ ((visibility ("default")))
#else
#error "Unknown platform/compiler"
#endif

#if __TBB_BUILD
#define TBB_EXPORT _EXPORT
#define TBB_EXPORT __TBB_EXPORT
#else
#define TBB_EXPORT
#endif

#if __TBBMALLOC_BUILD
#define TBBMALLOC_EXPORT _EXPORT
#define TBBMALLOC_EXPORT __TBB_EXPORT
#else
#define TBBMALLOC_EXPORT
#endif

#if __TBBMALLOCPROXY_BUILD
#define TBBMALLOCPROXY_EXPORT __TBB_EXPORT
#else
#define TBBMALLOCPROXY_EXPORT
#endif

#if __TBBBIND_BUILD
#define TBBBIND_EXPORT _EXPORT
#define TBBBIND_EXPORT __TBB_EXPORT
#else
#define TBBBIND_EXPORT
#endif
Expand Down
4 changes: 2 additions & 2 deletions src/tbb/queuing_rw_mutex.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2022 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -608,7 +608,7 @@ bool __TBB_EXPORTED_FUNC downgrade_to_reader(d1::queuing_rw_mutex::scoped_lock&
return queuing_rw_mutex_impl::downgrade_to_reader(s);
}

void __TBB_EXPORTED_FUNC construct(d1::queuing_rw_mutex& m) {
TBB_EXPORT void __TBB_EXPORTED_FUNC construct(d1::queuing_rw_mutex& m) {
queuing_rw_mutex_impl::construct(m);
}

Expand Down
2 changes: 1 addition & 1 deletion src/tbbbind/tbb_bind.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -528,7 +528,7 @@ TBBBIND_EXPORT int __TBB_internal_get_default_concurrency(int numa_id, int core_
return system_topology::instance().get_default_concurrency(numa_id, core_type_id, max_threads_per_core);
}

void __TBB_internal_destroy_system_topology() {
TBBBIND_EXPORT void __TBB_internal_destroy_system_topology() {
return system_topology::destroy();
}

Expand Down
2 changes: 1 addition & 1 deletion src/tbbmalloc/frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2951,7 +2951,7 @@ extern "C" void scalable_free(void *object)
}

#if MALLOC_ZONE_OVERLOAD_ENABLED
extern "C" void __TBB_malloc_free_definite_size(void *object, size_t size)
extern "C" TBBMALLOC_EXPORT void __TBB_malloc_free_definite_size(void *object, size_t size)
{
internalPoolFree(defaultMemPool, object, size);
}
Expand Down
60 changes: 30 additions & 30 deletions src/tbbmalloc_proxy/proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ static inline void initPageSize()
2) check that dlsym("malloc") found something different from our replacement malloc
*/

extern "C" void *__TBB_malloc_proxy(size_t) __TBB_ALIAS_ATTR_COPY(malloc);
extern "C" TBBMALLOCPROXY_EXPORT void *__TBB_malloc_proxy(size_t) __TBB_ALIAS_ATTR_COPY(malloc);

static void *orig_msize;

Expand Down Expand Up @@ -184,23 +184,23 @@ inline void InitOrigPointers() {}

#endif // MALLOC_UNIXLIKE_OVERLOAD_ENABLED and MALLOC_ZONE_OVERLOAD_ENABLED

void *PREFIX(malloc)(ZONE_ARG size_t size) __THROW
TBBMALLOCPROXY_EXPORT void *PREFIX(malloc)(ZONE_ARG size_t size) __THROW
{
return scalable_malloc(size);
}

void *PREFIX(calloc)(ZONE_ARG size_t num, size_t size) __THROW
TBBMALLOCPROXY_EXPORT void *PREFIX(calloc)(ZONE_ARG size_t num, size_t size) __THROW
{
return scalable_calloc(num, size);
}

void PREFIX(free)(ZONE_ARG void *object) __THROW
TBBMALLOCPROXY_EXPORT void PREFIX(free)(ZONE_ARG void *object) __THROW
{
InitOrigPointers();
__TBB_malloc_safer_free(object, (void (*)(void*))orig_free);
}

void *PREFIX(realloc)(ZONE_ARG void* ptr, size_t sz) __THROW
TBBMALLOCPROXY_EXPORT void *PREFIX(realloc)(ZONE_ARG void* ptr, size_t sz) __THROW
{
InitOrigPointers();
return __TBB_malloc_safer_realloc(ptr, sz, orig_realloc);
Expand All @@ -209,13 +209,13 @@ void *PREFIX(realloc)(ZONE_ARG void* ptr, size_t sz) __THROW
/* The older *NIX interface for aligned allocations;
it's formally substituted by posix_memalign and deprecated,
so we do not expect it to cause cyclic dependency with C RTL. */
void *PREFIX(memalign)(ZONE_ARG size_t alignment, size_t size) __THROW
TBBMALLOCPROXY_EXPORT void *PREFIX(memalign)(ZONE_ARG size_t alignment, size_t size) __THROW
{
return scalable_aligned_malloc(size, alignment);
}

/* valloc allocates memory aligned on a page boundary */
void *PREFIX(valloc)(ZONE_ARG size_t size) __THROW
TBBMALLOCPROXY_EXPORT void *PREFIX(valloc)(ZONE_ARG size_t size) __THROW
{
if (! memoryPageSize) initPageSize();

Expand All @@ -229,23 +229,23 @@ void *PREFIX(valloc)(ZONE_ARG size_t size) __THROW

// match prototype from system headers
#if __ANDROID__
size_t malloc_usable_size(const void *ptr) __THROW
TBBMALLOCPROXY_EXPORT size_t malloc_usable_size(const void *ptr) __THROW
#else
size_t malloc_usable_size(void *ptr) __THROW
TBBMALLOCPROXY_EXPORT size_t malloc_usable_size(void *ptr) __THROW
#endif
{
InitOrigPointers();
return __TBB_malloc_safer_msize(const_cast<void*>(ptr), (size_t (*)(void*))orig_msize);
}

int posix_memalign(void **memptr, size_t alignment, size_t size) __THROW
TBBMALLOCPROXY_EXPORT int posix_memalign(void **memptr, size_t alignment, size_t size) __THROW
{
return scalable_posix_memalign(memptr, alignment, size);
}

/* pvalloc allocates smallest set of complete pages which can hold
the requested number of bytes. Result is aligned on page boundary. */
void *pvalloc(size_t size) __THROW
TBBMALLOCPROXY_EXPORT void *pvalloc(size_t size) __THROW
{
if (! memoryPageSize) initPageSize();
// align size up to the page size,
Expand All @@ -255,13 +255,13 @@ void *pvalloc(size_t size) __THROW
return scalable_aligned_malloc(size, memoryPageSize);
}

int mallopt(int /*param*/, int /*value*/) __THROW
TBBMALLOCPROXY_EXPORT int mallopt(int /*param*/, int /*value*/) __THROW
{
return 1;
}

#if defined(__GLIBC__) || defined(__ANDROID__)
struct mallinfo mallinfo() __THROW
TBBMALLOCPROXY_EXPORT struct mallinfo mallinfo() __THROW
{
struct mallinfo m;
memset(&m, 0, sizeof(struct mallinfo));
Expand All @@ -274,30 +274,30 @@ struct mallinfo mallinfo() __THROW
// Android doesn't have malloc_usable_size, provide it to be compatible
// with Linux, in addition overload dlmalloc_usable_size() that presented
// under Android.
size_t dlmalloc_usable_size(const void *ptr) __TBB_ALIAS_ATTR_COPY(malloc_usable_size);
TBBMALLOCPROXY_EXPORT size_t dlmalloc_usable_size(const void *ptr) __TBB_ALIAS_ATTR_COPY(malloc_usable_size);
#else // __ANDROID__
// TODO: consider using __typeof__ to guarantee the correct declaration types
// C11 function, supported starting GLIBC 2.16
void *aligned_alloc(size_t alignment, size_t size) __TBB_ALIAS_ATTR_COPY(memalign);
TBBMALLOCPROXY_EXPORT void *aligned_alloc(size_t alignment, size_t size) __TBB_ALIAS_ATTR_COPY(memalign);
// Those non-standard functions are exported by GLIBC, and might be used
// in conjunction with standard malloc/free, so we must overload them.
// Bionic doesn't have them. Not removing from the linker scripts,
// as absent entry points are ignored by the linker.

void *__libc_malloc(size_t size) __TBB_ALIAS_ATTR_COPY(malloc);
void *__libc_calloc(size_t num, size_t size) __TBB_ALIAS_ATTR_COPY(calloc);
void *__libc_memalign(size_t alignment, size_t size) __TBB_ALIAS_ATTR_COPY(memalign);
void *__libc_pvalloc(size_t size) __TBB_ALIAS_ATTR_COPY(pvalloc);
void *__libc_valloc(size_t size) __TBB_ALIAS_ATTR_COPY(valloc);
TBBMALLOCPROXY_EXPORT void *__libc_malloc(size_t size) __TBB_ALIAS_ATTR_COPY(malloc);
TBBMALLOCPROXY_EXPORT void *__libc_calloc(size_t num, size_t size) __TBB_ALIAS_ATTR_COPY(calloc);
TBBMALLOCPROXY_EXPORT void *__libc_memalign(size_t alignment, size_t size) __TBB_ALIAS_ATTR_COPY(memalign);
TBBMALLOCPROXY_EXPORT void *__libc_pvalloc(size_t size) __TBB_ALIAS_ATTR_COPY(pvalloc);
TBBMALLOCPROXY_EXPORT void *__libc_valloc(size_t size) __TBB_ALIAS_ATTR_COPY(valloc);

// call original __libc_* to support naive replacement of free via __libc_free etc
void __libc_free(void *ptr)
TBBMALLOCPROXY_EXPORT void __libc_free(void *ptr)
{
InitOrigPointers();
__TBB_malloc_safer_free(ptr, (void (*)(void*))orig_libc_free);
}

void *__libc_realloc(void *ptr, size_t size)
TBBMALLOCPROXY_EXPORT void *__libc_realloc(void *ptr, size_t size)
{
InitOrigPointers();
return __TBB_malloc_safer_realloc(ptr, size, orig_libc_realloc);
Expand All @@ -308,31 +308,31 @@ void *__libc_realloc(void *ptr, size_t size)

/*** replacements for global operators new and delete ***/

void* operator new(size_t sz) {
TBBMALLOCPROXY_EXPORT void* operator new(size_t sz) {
return InternalOperatorNew(sz);
}
void* operator new[](size_t sz) {
TBBMALLOCPROXY_EXPORT void* operator new[](size_t sz) {
return InternalOperatorNew(sz);
}
void operator delete(void* ptr) noexcept {
TBBMALLOCPROXY_EXPORT void operator delete(void* ptr) noexcept {
InitOrigPointers();
__TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free);
}
void operator delete[](void* ptr) noexcept {
TBBMALLOCPROXY_EXPORT void operator delete[](void* ptr) noexcept {
InitOrigPointers();
__TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free);
}
void* operator new(size_t sz, const std::nothrow_t&) noexcept {
TBBMALLOCPROXY_EXPORT void* operator new(size_t sz, const std::nothrow_t&) noexcept {
return scalable_malloc(sz);
}
void* operator new[](std::size_t sz, const std::nothrow_t&) noexcept {
TBBMALLOCPROXY_EXPORT void* operator new[](std::size_t sz, const std::nothrow_t&) noexcept {
return scalable_malloc(sz);
}
void operator delete(void* ptr, const std::nothrow_t&) noexcept {
TBBMALLOCPROXY_EXPORT void operator delete(void* ptr, const std::nothrow_t&) noexcept {
InitOrigPointers();
__TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free);
}
void operator delete[](void* ptr, const std::nothrow_t&) noexcept {
TBBMALLOCPROXY_EXPORT void operator delete[](void* ptr, const std::nothrow_t&) noexcept {
InitOrigPointers();
__TBB_malloc_safer_free(ptr, (void (*)(void*))orig_free);
}
Expand Down
4 changes: 2 additions & 2 deletions src/tbbmalloc_proxy/proxy.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -37,7 +37,7 @@ extern "C" {
TBBMALLOC_EXPORT size_t __TBB_malloc_safer_aligned_msize( void *ptr, size_t, size_t, size_t (*orig_msize_crt80d)(void*,size_t,size_t));

#if MALLOC_ZONE_OVERLOAD_ENABLED
void __TBB_malloc_free_definite_size(void *object, size_t size);
TBBMALLOC_EXPORT void __TBB_malloc_free_definite_size(void *object, size_t size);
#endif
} // extern "C"

Expand Down
4 changes: 2 additions & 2 deletions test/tbb/test_dynamic_link.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2021 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -31,7 +31,7 @@ enum FOO_TYPE {
#if _WIN32 || _WIN64
#define TEST_EXPORT
#else
#define TEST_EXPORT extern "C"
#define TEST_EXPORT extern "C" __TBB_EXPORT
#endif /* _WIN32 || _WIN64 */

// foo "implementations".
Expand Down
3 changes: 2 additions & 1 deletion test/tbb/test_tbb_header.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2023 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -165,6 +165,7 @@ static void TestExceptionClassesExports () {
TestExceptionClassExports( std::out_of_range("test"), tbb::detail::exception_id::invalid_key );
TestExceptionClassExports( tbb::user_abort(), tbb::detail::exception_id::user_abort );
TestExceptionClassExports( std::runtime_error("test"), tbb::detail::exception_id::bad_tagged_msg_cast );
TestExceptionClassExports( tbb::unsafe_wait("test"), tbb::detail::exception_id::unsafe_wait );
}

#if __TBB_CPF_BUILD
Expand Down
4 changes: 3 additions & 1 deletion test/tbbmalloc/test_malloc_atexit.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (c) 2005-2022 Intel Corporation
Copyright (c) 2005-2024 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -33,6 +33,8 @@
#if _USRDLL
#if _WIN32||_WIN64
extern __declspec(dllexport)
#else
__TBB_EXPORT
#endif
bool dll_isMallocOverloaded()
#else
Expand Down
Loading

0 comments on commit 4b02f62

Please sign in to comment.