Skip to content

Commit 1625f5b

Browse files
authored
Export std hash template specializations from dylibs (#7618)
Use explicit visibility to force std::hash template specializations 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 llvm/llvm-project#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).
1 parent df4285e commit 1625f5b

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ if(BUILD_STATIC_LIB)
462462
else()
463463
message(STATUS "Building libbinaryen as shared library.")
464464
add_library(binaryen SHARED)
465+
if(LINUX)
466+
# Disable interposition and resolve Binaryen symbols locally.
467+
add_link_flag("-Bsymbolic")
468+
endif()
465469
endif()
466470
target_link_libraries(binaryen Threads::Threads)
467471
if(BUILD_LLVM_DWARF)

src/compiler-support.h

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,23 @@
3131
#define WASM_BUILTIN_UNREACHABLE __assume(false)
3232
#endif
3333

34+
// Forces symbols to be exported from libbinaryen dynamic library. Currently
35+
// we are just using the default flags, causing most of our symbols to have
36+
// "default" visibility, meaning they can all be used from the tool sources.
37+
// However a recent libc++ change caused functions declared in namespace std
38+
// (e.g. hash template specializations) to have hidden visibility, inherited.
39+
// from the namespece (see https://github.com/llvm/llvm-project/pull/131156).
40+
// So this macro forces them to be exported. Currently it is only applied to
41+
// the hash specializations that are defined in libbinaryen and used in the
42+
// tool code. In the future if we want to compile libbinaryen with
43+
// -fvisibility-hidden or use a DLL on Windows, we'll need
44+
// to explicitly annotate everything we want to export. But that's probably
45+
// only useful if we want external users to link against libbinaryen.so
46+
// (currently we don't; it's only used to reduce our install size).
47+
#if defined(__ELF__) || defined(__MACH__)
48+
#define DLLEXPORT [[gnu::visibility("default")]]
49+
#else
50+
#define DLLEXPORT
51+
#endif
52+
3453
#endif // wasm_compiler_support_h

src/wasm-type-shape.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <functional>
2121
#include <vector>
2222

23+
#include "compiler-support.h"
2324
#include "wasm-features.h"
2425
#include "wasm-type.h"
2526

@@ -74,7 +75,7 @@ namespace std {
7475

7576
template<> class hash<wasm::RecGroupShape> {
7677
public:
77-
size_t operator()(const wasm::RecGroupShape& shape) const;
78+
DLLEXPORT size_t operator()(const wasm::RecGroupShape& shape) const;
7879
};
7980

8081
} // namespace std

src/wasm-type.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <variant>
2626
#include <vector>
2727

28+
#include "compiler-support.h"
2829
#include "support/index.h"
2930
#include "support/name.h"
3031
#include "support/parent_index_iterator.h"
@@ -1005,35 +1006,35 @@ namespace std {
10051006

10061007
template<> class hash<wasm::Type> {
10071008
public:
1008-
size_t operator()(const wasm::Type&) const;
1009+
DLLEXPORT size_t operator()(const wasm::Type&) const;
10091010
};
10101011
template<> class hash<wasm::Signature> {
10111012
public:
1012-
size_t operator()(const wasm::Signature&) const;
1013+
DLLEXPORT size_t operator()(const wasm::Signature&) const;
10131014
};
10141015
template<> class hash<wasm::Continuation> {
10151016
public:
1016-
size_t operator()(const wasm::Continuation&) const;
1017+
DLLEXPORT size_t operator()(const wasm::Continuation&) const;
10171018
};
10181019
template<> class hash<wasm::Field> {
10191020
public:
1020-
size_t operator()(const wasm::Field&) const;
1021+
DLLEXPORT size_t operator()(const wasm::Field&) const;
10211022
};
10221023
template<> class hash<wasm::Struct> {
10231024
public:
1024-
size_t operator()(const wasm::Struct&) const;
1025+
DLLEXPORT size_t operator()(const wasm::Struct&) const;
10251026
};
10261027
template<> class hash<wasm::Array> {
10271028
public:
1028-
size_t operator()(const wasm::Array&) const;
1029+
DLLEXPORT size_t operator()(const wasm::Array&) const;
10291030
};
10301031
template<> class hash<wasm::HeapType> {
10311032
public:
1032-
size_t operator()(const wasm::HeapType&) const;
1033+
DLLEXPORT size_t operator()(const wasm::HeapType&) const;
10331034
};
10341035
template<> class hash<wasm::RecGroup> {
10351036
public:
1036-
size_t operator()(const wasm::RecGroup&) const;
1037+
DLLEXPORT size_t operator()(const wasm::RecGroup&) const;
10371038
};
10381039

10391040
} // namespace std

0 commit comments

Comments
 (0)