Skip to content

Commit d854643

Browse files
Andrew Savonichevbader
authored andcommitted
[SYCL] Add linker script to limit exported symbols (#955)
Template function instantiations from libstdc++ headers are exported from libsycl.so as weak symbols by default, and they become a part of libsycl.so ABI. This includes libstdc++ internal functions (e.g. classes defined in std::__detail namespace), which, unlike standard C++ classes (like std::vector), are not forward-compatible. Host program is also compiled with libstdc++ headers, so it may also contain the same weak symbols. When libsycl.so is loaded by a host program, loader resolves its symbols for internal libstdc++ functions to the corresponding symbols in the host program. They may be incompatible, (e.g. when the host program is compiled with different version of libstdc++), so libsycl.so is going to crash or execute incorrectly. Linker script limits symbols that we actually export from the library. Template function instantiations become local, so loader will no longer attempt to resolve them. This patch does not use extern "C++" matcher for C++ functions, because vtable and typeinfo symbols make extern "C++" patterns more complicated than patterns against mangled names. With extern "C++" we have to match for "vtable for cl::sycl::foo", but not match for "vtable for std::__internal<cl::sycl::foo>". Also cleanup functions that were never meant to be exported. Signed-off-by: Andrew Savonichev <[email protected]>
1 parent 731d639 commit d854643

File tree

5 files changed

+52
-7
lines changed

5 files changed

+52
-7
lines changed

sycl/include/CL/sycl/detail/common.hpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,19 @@
2020
#define STRINGIFY_LINE_HELP(s) #s
2121
#define STRINGIFY_LINE(s) STRINGIFY_LINE_HELP(s)
2222

23+
namespace cl {
24+
namespace sycl {
25+
namespace detail {
26+
2327
const char *stringifyErrorCode(cl_int error);
2428

2529
static inline std::string codeToString(cl_int code){
2630
return std::string(std::to_string(code) + " (" +
2731
stringifyErrorCode(code) + ")");
2832
}
2933

34+
}}} // namespace cl::sycl::detail
35+
3036
#ifdef __SYCL_DEVICE_ONLY__
3137
// TODO remove this when 'assert' is supported in device code
3238
#define __SYCL_ASSERT(x)
@@ -46,7 +52,8 @@ static inline std::string codeToString(cl_int code){
4652
{ \
4753
auto code = expr; \
4854
if (code != CL_SUCCESS) { \
49-
std::cerr << OCL_ERROR_REPORT << codeToString(code) << std::endl; \
55+
std::cerr << OCL_ERROR_REPORT << cl::sycl::detail::codeToString(code) \
56+
<< std::endl; \
5057
} \
5158
}
5259
#endif
@@ -58,7 +65,7 @@ static inline std::string codeToString(cl_int code){
5865
{ \
5966
auto code = expr; \
6067
if (code != CL_SUCCESS) { \
61-
throw exc(OCL_ERROR_REPORT + codeToString(code), code); \
68+
throw exc(OCL_ERROR_REPORT + cl::sycl::detail::codeToString(code), code); \
6269
} \
6370
}
6471
#define REPORT_OCL_ERR_TO_EXC_THROW(code, exc) REPORT_OCL_ERR_TO_EXC(code, exc)

sycl/include/CL/sycl/exception.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ class exception: public std::exception {
4747

4848
exception(const string_class &Msg, const cl_int CLErr = CL_SUCCESS,
4949
shared_ptr_class<context> Context = nullptr)
50-
: MMsg(Msg + " " + codeToString(CLErr)), MCLErr(CLErr),
50+
: MMsg(Msg + " " + detail::codeToString(CLErr)), MCLErr(CLErr),
5151
MContext(Context) {}
5252
};
5353

sycl/source/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,13 @@ function(add_sycl_rt_library LIB_NAME)
2020
if (MSVC)
2121
target_compile_definitions(${LIB_NAME} PRIVATE __SYCL_BUILD_SYCL_DLL )
2222
target_link_libraries(${LIB_NAME} PRIVATE shlwapi)
23+
else()
24+
set(linker_script "${CMAKE_CURRENT_SOURCE_DIR}/ld-version-script.txt")
25+
target_link_libraries(
26+
${LIB_NAME} PRIVATE "-Wl,--version-script=${linker_script}")
27+
set_target_properties(${LIB_NAME} PROPERTIES LINK_DEPENDS ${linker_script})
2328
endif()
29+
2430
target_include_directories(
2531
${LIB_NAME} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} "${sycl_inc_dir}")
2632
target_link_libraries(${LIB_NAME}

sycl/source/detail/common.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
#include <CL/sycl/detail/common.hpp>
1010
#include <CL/sycl/detail/common_info.hpp>
1111

12+
namespace cl {
13+
namespace sycl {
14+
namespace detail {
15+
1216
const char *stringifyErrorCode(cl_int error) {
1317
switch (error) {
1418
case CL_INVALID_ACCELERATOR_INTEL:
@@ -213,10 +217,6 @@ const char *stringifyErrorCode(cl_int error) {
213217
}
214218
}
215219

216-
namespace cl {
217-
namespace sycl {
218-
namespace detail {
219-
220220
vector_class<string_class> split_string(const string_class &str,
221221
char delimeter) {
222222
vector_class<string_class> result;

sycl/source/ld-version-script.txt

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
/* Do not use extern "C++" matcher for C++ functions, */
3+
/* because vtable and typeinfo symbols make extern "C++" patterns more */
4+
/* complicated than patterns against mangled names. */
5+
/* */
6+
/* With extern "C++" we have to match for "vtable for cl::sycl::foo", but */
7+
/* not match for "vtable for std::__internal<cl::sycl::foo>". */
8+
9+
global:
10+
/* Export everything from cl::sycl namespace */
11+
_ZNK2cl4sycl*; /* function */
12+
_ZN2cl4sycl*; /* function */
13+
_ZTIN2cl4sycl*; /* typeinfo */
14+
_ZTSN2cl4sycl*; /* typeinfo name */
15+
_ZTVN2cl4sycl*; /* vtable */
16+
17+
/* Some functions are also in cl::__host_std, export them as well */
18+
_ZN2cl10__host_std*;
19+
20+
/* Export SPIR-V built-ins for host device */
21+
_Z23__spirv_GroupWaitEvents*;
22+
_Z22__spirv_ControlBarrier*;
23+
_Z21__spirv_MemoryBarrier*;
24+
_Z20__spirv_ocl_prefetch*;
25+
26+
/* Export offload image hooks */
27+
__tgt_register_lib;
28+
__tgt_unregister_lib;
29+
30+
local:
31+
*;
32+
};

0 commit comments

Comments
 (0)