summaryrefslogtreecommitdiffstats
path: root/llvm
diff options
context:
space:
mode:
authorMichal Gorny <mgorny@gentoo.org>2017-11-27 22:23:09 +0000
committerMichal Gorny <mgorny@gentoo.org>2017-11-27 22:23:09 +0000
commit8eaa8ec8fc9591bc71675605a3cee24a17d16d3f (patch)
treefdfe95b495f1424d5f3930017260e9f0d98aa9d3 /llvm
parentd6b67eb15c3640c38d2e12f83373def07ca6fae9 (diff)
downloadbcm5719-llvm-8eaa8ec8fc9591bc71675605a3cee24a17d16d3f.tar.gz
bcm5719-llvm-8eaa8ec8fc9591bc71675605a3cee24a17d16d3f.zip
[cmake] Pass -Wl,-z,nodelete on Linux to prevent unloading
Prevent unloading shared libraries on Linux when dlclose() is called. This is necessary since command-line option parsing API relies on registering the global option instances in the option parser instance which can be loaded in a different shared library. Given that we can't reliably remove those options when a library is unloaded, the parser ends up containing dangling references. Since glibc has relatively complex library unloading rules, some of the LLVM libraries can be unloaded while others (including the Support library) stay loaded causing quite a mayhem. To reliably prevent that, just forbid unloading all libraries -- it's a very bad idea anyway. While the issue arguably happens only with BUILD_SHARED_LIBS, it may affect any library reusing llvm::cl interface. Based on patch provided Ross Hayward on https://bugs.gentoo.org/617154. Previously hit by Fedora back in Feb 2016: https://lists.freedesktop.org/archives/mesa-dev/2016-February/107242.html Differential Revision: https://reviews.llvm.org/D40459 llvm-svn: 319105
Diffstat (limited to 'llvm')
-rw-r--r--llvm/cmake/modules/HandleLLVMOptions.cmake8
-rw-r--r--llvm/unittests/Support/DynamicLibrary/CMakeLists.txt7
2 files changed, 15 insertions, 0 deletions
diff --git a/llvm/cmake/modules/HandleLLVMOptions.cmake b/llvm/cmake/modules/HandleLLVMOptions.cmake
index c5390371845..b5059a8a60e 100644
--- a/llvm/cmake/modules/HandleLLVMOptions.cmake
+++ b/llvm/cmake/modules/HandleLLVMOptions.cmake
@@ -151,6 +151,14 @@ if(NOT (${CMAKE_SYSTEM_NAME} MATCHES "Darwin" OR WIN32 OR CYGWIN OR
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,defs")
endif()
+# Pass -Wl,-z,nodelete. This makes sure our shared libraries are not unloaded
+# by dlclose(). We need that since the CLI API relies on cross-references
+# between global objects which became horribly broken when one of the libraries
+# is unloaded.
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-z,nodelete")
+endif()
+
function(append value)
foreach(variable ${ARGN})
diff --git a/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt b/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt
index 9355979221a..c6201b1ad31 100644
--- a/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt
+++ b/llvm/unittests/Support/DynamicLibrary/CMakeLists.txt
@@ -24,5 +24,12 @@ function(dynlib_add_module NAME)
add_dependencies(DynamicLibraryTests ${NAME})
endfunction(dynlib_add_module)
+# Revert -Wl,-z,nodelete on this test since it relies on the file
+# being unloaded.
+if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
+ string(REPLACE "-Wl,-z,nodelete" "" CMAKE_SHARED_LINKER_FLAGS
+ ${CMAKE_SHARED_LINKER_FLAGS})
+endif()
+
dynlib_add_module(PipSqueak)
dynlib_add_module(SecondLib)
OpenPOWER on IntegriCloud