Comment 12 for bug 1819013

Revision history for this message
Jo Shields (directhex) wrote :

builder@xam-power8-1:~$ uname -m
ppc64le
builder@xam-power8-1:~$ objdump -T /usr/lib/firefox/libxul.so | grep GLIBCXX_3.4.22
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.22 _ZNSt6thread15_M_start_threadESt10unique_ptrINS_6_StateESt14default_deleteIS1_EEPFvvE
0000000000000000 DF *UND* 0000000000000000 GLIBCXX_3.4.22 _ZNSt6thread6_StateD2Ev

vs

root@breakfast:/# uname -m
x86_64
root@breakfast:/# objdump -T /usr/lib/firefox/libxul.so | grep GLIBCXX_3.4.22

The mangling of std::thread::_M_start_thread(std::unique_ptr<std::thread::_State, std::default_delete<std::thread::_State> >, void (*)()) and std::thread::_State::~_State() is supposed to be handled by the block in build/unix/stdc++compat/stdc++compat.cpp starting at line 104:

#if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 21)
/* Expose the definitions for the old ABI, allowing us to call its functions */
# define _GLIBCXX_THREAD_ABI_COMPAT 1
# include <thread>

namespace std {
/* The old ABI has a thread::_M_start_thread(shared_ptr<_Impl_base>),
 * while the new has thread::_M_start_thread(unique_ptr<_State>, void(*)()).
 * There is an intermediate ABI at version 3.4.21, with
 * thread::_M_start_thread(shared_ptr<_Impl_base>, void(*)()).
 * The void(*)() parameter is only there to keep a reference to pthread_create
 * on the caller side, and is unused in the implementation
 * We're creating an entry point for the new and intermediate ABIs, and make
 * them call the old ABI. */

__attribute__((weak)) void thread::_M_start_thread(shared_ptr<_Impl_base> impl,
                                                   void (*)()) {
  _M_start_thread(std::move(impl));
}

# if MOZ_LIBSTDCXX_VERSION >= GLIBCXX_VERSION(3, 4, 22)
/* We need a _Impl_base-derived class wrapping a _State to call the old ABI
 * from what we got by diverting the new API */
struct StateWrapper : public thread::_Impl_base {
  unique_ptr<thread::_State> mState;

  StateWrapper(unique_ptr<thread::_State> aState) : mState(std::move(aState)) {}

  void _M_run() override { mState->_M_run(); }
};

__attribute__((weak)) void thread::_M_start_thread(unique_ptr<_State> aState,
                                                   void (*)()) {
  auto impl = std::make_shared<StateWrapper>(std::move(aState));
  _M_start_thread(std::move(impl));
}

/* For some reason this is a symbol exported by new versions of libstdc++,
 * even though the destructor is default there too */
__attribute__((weak)) thread::_State::~_State() = default;
# endif
} // namespace std
#endif

I don't know what's broken in the build process causing this code not to be included in ppc64el builds.