> 1. a "payload" executable built with "-fPIC -pie" (or "-fPIE -pie") > which uses threads and thread-local storage; > > 2. a "loader" executable, which dlopen()s the payload binary and calls > its main(). > > Starting the loader results in a segfault at thread creation time. > Building payload with "-fPIC -shared" results in normally working > loader, but I need to be able to launch payload both directly and via > the loader. > > Is this a bug or I'm doing something wrong? When you build a binary with -pie, the linker makes an executable, not a shared library, and in general you can't dlopen an executable, even if it's position-independent. There are a few reasons for this, but the one I suspect is causing the segfault is that the thread model used in an executable is different from the model used in a shared library. In an executable (including position-independent executables), all the TLS variables are allocated at fixed tp-relative offsets, and the code is bound to those offsets. When you load a shared library, the dynamic loader expects to be able to allocate the library's TLS variables at dynamic offsets, and it expects that the code will use the GOT to find these offsets. Even when you compile your payload with -fPIC, which generates TLS code compatible with a shared library, the linker will rewrite the code where it can to take advantage of the fixed offsets, knowing that it's building an executable. -cary