diff --git a/CMakeLists.txt b/CMakeLists.txt index 16e2add800f..0279e7d3e43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -462,6 +462,10 @@ if(BUILD_STATIC_LIB) else() message(STATUS "Building libbinaryen as shared library.") add_library(binaryen SHARED) + if(LINUX) + # Disable interposition and resolve Binaryen symbols locally. + add_link_flag("-Bsymbolic") + endif() endif() target_link_libraries(binaryen Threads::Threads) if(BUILD_LLVM_DWARF) diff --git a/src/compiler-support.h b/src/compiler-support.h index a3485919086..50883868335 100644 --- a/src/compiler-support.h +++ b/src/compiler-support.h @@ -31,4 +31,23 @@ #define WASM_BUILTIN_UNREACHABLE __assume(false) #endif +// Forces symbols to be exported from libbinaryen dynamic library. Currently +// we are just using the default flags, causing most of our symbols to have +// "default" visibility, meaning they can all be used from the tool sources. +// However a recent libc++ change caused functions declared in namespace std +// (e.g. hash template specializations) to have hidden visibility, inherited. +// from the namespece (see https://github.com/llvm/llvm-project/pull/131156). +// So this macro forces them to be exported. Currently it is only applied to +// the hash specializations that are defined in libbinaryen and used in the +// tool code. In the future if we want to compile libbinaryen with +// -fvisibility-hidden or use a DLL on Windows, we'll need +// to explicitly annotate everything we want to export. But that's probably +// only useful if we want external users to link against libbinaryen.so +// (currently we don't; it's only used to reduce our install size). +#if defined(__ELF__) || defined(__MACH__) +#define DLLEXPORT [[gnu::visibility("default")]] +#else +#define DLLEXPORT +#endif + #endif // wasm_compiler_support_h diff --git a/src/wasm-type-shape.h b/src/wasm-type-shape.h index e72f28dd530..3fe43b7f36e 100644 --- a/src/wasm-type-shape.h +++ b/src/wasm-type-shape.h @@ -20,6 +20,7 @@ #include #include +#include "compiler-support.h" #include "wasm-features.h" #include "wasm-type.h" @@ -74,7 +75,7 @@ namespace std { template<> class hash { public: - size_t operator()(const wasm::RecGroupShape& shape) const; + DLLEXPORT size_t operator()(const wasm::RecGroupShape& shape) const; }; } // namespace std diff --git a/src/wasm-type.h b/src/wasm-type.h index b5e9a88a3c6..d10893abf61 100644 --- a/src/wasm-type.h +++ b/src/wasm-type.h @@ -25,6 +25,7 @@ #include #include +#include "compiler-support.h" #include "support/index.h" #include "support/name.h" #include "support/parent_index_iterator.h" @@ -1005,35 +1006,35 @@ namespace std { template<> class hash { public: - size_t operator()(const wasm::Type&) const; + DLLEXPORT size_t operator()(const wasm::Type&) const; }; template<> class hash { public: - size_t operator()(const wasm::Signature&) const; + DLLEXPORT size_t operator()(const wasm::Signature&) const; }; template<> class hash { public: - size_t operator()(const wasm::Continuation&) const; + DLLEXPORT size_t operator()(const wasm::Continuation&) const; }; template<> class hash { public: - size_t operator()(const wasm::Field&) const; + DLLEXPORT size_t operator()(const wasm::Field&) const; }; template<> class hash { public: - size_t operator()(const wasm::Struct&) const; + DLLEXPORT size_t operator()(const wasm::Struct&) const; }; template<> class hash { public: - size_t operator()(const wasm::Array&) const; + DLLEXPORT size_t operator()(const wasm::Array&) const; }; template<> class hash { public: - size_t operator()(const wasm::HeapType&) const; + DLLEXPORT size_t operator()(const wasm::HeapType&) const; }; template<> class hash { public: - size_t operator()(const wasm::RecGroup&) const; + DLLEXPORT size_t operator()(const wasm::RecGroup&) const; }; } // namespace std