Bug 1464084 - Don't export std::thread::_M_start_thread symbols with --enable-stdcxx-compat. r=froydnj draft
authorMike Hommey <mh+mozilla@glandium.org>
Fri, 01 Jun 2018 08:10:25 +0900
changeset 803220 8146edc5d2d842ef37f025526eacf8ece9767b97
parent 803219 f890524db5be2e6d5713e158f465a2b7158dbf8d
push id112046
push userbmo:mh+mozilla@glandium.org
push dateSat, 02 Jun 2018 05:11:11 +0000
reviewersfroydnj
bugs1464084
milestone62.0a1
Bug 1464084 - Don't export std::thread::_M_start_thread symbols with --enable-stdcxx-compat. r=froydnj This relies on the fact that providing multiple --version-script combines them all, so we effectively create a new symbol version that has no global symbol, but hides the std::thread::_M_start_thread symbols. This version script trick happens to work with BFD ld, gold, and lld. The downside is that when providing multiple --version-script's, ld doesn't want any of them to have no version at all. So for the libraries that do already have a version script (through SYMBOLS_FILE), we use a version where there used to be none, using the library name as the version. Practically speaking, this binds the libraries a little closer than they used to be, kind of non-flat namespace on OSX (which is the default there), meaning the dynamic linker will actively want to use symbols from those libraries instead of a system library that might happen to have the same symbol name.
build/unix/stdc++compat/hide_std.ld
build/unix/stdc++compat/moz.build
python/mozbuild/mozbuild/action/generate_symbols_file.py
testing/cppunittest.ini
new file mode 100644
--- /dev/null
+++ b/build/unix/stdc++compat/hide_std.ld
@@ -0,0 +1,5 @@
+hidden {
+  local:
+    # std::thread::_M_start_thread(...)
+    _ZNSt6thread15_M_start_thread*;
+};
--- a/build/unix/stdc++compat/moz.build
+++ b/build/unix/stdc++compat/moz.build
@@ -18,8 +18,10 @@ FORCE_STATIC_LIB = True
 
 NO_PGO = True
 
 DisableStlWrapping()
 COMPILE_FLAGS['CLANG_PLUGIN'] = []
 
 DEFINES['MOZ_LIBSTDCXX_VERSION'] = CONFIG['MOZ_LIBSTDCXX_TARGET_VERSION']
 HOST_DEFINES['MOZ_LIBSTDCXX_VERSION'] = CONFIG['MOZ_LIBSTDCXX_HOST_VERSION']
+
+OS_LIBS += ['-Wl,--version-script,%s/hide_std.ld' % SRCDIR]
--- a/python/mozbuild/mozbuild/action/generate_symbols_file.py
+++ b/python/mozbuild/mozbuild/action/generate_symbols_file.py
@@ -37,16 +37,18 @@ def generate_symbols_file(output, *args)
     else:
         pp.context['DATA'] = ''
     pp.out = StringIO()
     pp.do_filter('substitution')
     pp.do_include(input)
 
     symbols = [s.strip() for s in pp.out.getvalue().splitlines() if s.strip()]
 
+    libname, ext = os.path.splitext(os.path.basename(output.name))
+
     if buildconfig.substs['OS_TARGET'] == 'WINNT':
         # A def file is generated for MSVC link.exe that looks like the
         # following:
         # LIBRARY library.dll
         # EXPORTS
         #   symbol1
         #   symbol2
         #   ...
@@ -61,31 +63,30 @@ def generate_symbols_file(output, *args)
         #   data_symbol1 @DATA@
         #   data_symbol2 @DATA@
         #   ...
         # The DATA variable is "simply" expanded by the preprocessor, to
         # nothing on non-Windows, such that we only get the symbol name on
         # those platforms, and to DATA on Windows, so that the "DATA" part
         # is, in fact, part of the symbol name as far as the symbols variable
         # is concerned.
-        libname, ext = os.path.splitext(os.path.basename(output.name))
         assert ext == '.def'
         output.write('LIBRARY %s\nEXPORTS\n  %s\n'
                      % (libname, '\n  '.join(symbols)))
     elif buildconfig.substs['GCC_USE_GNU_LD']:
         # A linker version script is generated for GNU LD that looks like the
         # following:
-        # {
+        # liblibrary.so {
         # global:
         #   symbol1;
         #   symbol2;
         #   ...
         # local:
         #   *;
         # };
-        output.write('{\nglobal:\n  %s;\nlocal:\n  *;\n};'
-                     % ';\n  '.join(symbols))
+        output.write('%s {\nglobal:\n  %s;\nlocal:\n  *;\n};'
+                     % (libname, ';\n  '.join(symbols)))
     elif buildconfig.substs['OS_TARGET'] == 'Darwin':
         # A list of symbols is generated for Apple ld that simply lists all
         # symbols, with an underscore prefix.
         output.write(''.join('_%s\n' % s for s in symbols))
 
     return set(pp.includes)
--- a/testing/cppunittest.ini
+++ b/testing/cppunittest.ini
@@ -38,17 +38,16 @@ skip-if = os == 'android' # Bug 1147630
 [TestRollingMean]
 [TestScopeExit]
 [TestSegmentedVector]
 [TestSHA1]
 [TestSmallPointerArray]
 [TestSaturate]
 [TestSplayTree]
 [TestSPSCQueue]
-skip-if = os == 'linux' # Bug 1464084
 [TestSyncRunnable]
 [TestTemplateLib]
 [TestTuple]
 [TestTypeTraits]
 [TestTypedEnum]
 [TestUniquePtr]
 [TestVariant]
 [TestVector]