This is the mail archive of the
gcc-help@gcc.gnu.org
mailing list for the GCC project.
Re: Segfault calling dlopen()'ed executable built with -pie and using TLS
- From: Cary Coutant <ccoutant at gmail dot com>
- To: intelfx at intelfx dot name
- Cc: gcc-help at gcc dot gnu dot org
- Date: Thu, 14 Apr 2016 09:41:46 -0700
- Subject: Re: Segfault calling dlopen()'ed executable built with -pie and using TLS
- Authentication-results: sourceware.org; auth=none
- References: <1460617920 dot 6454 dot 14 dot camel at intelfx dot name>
> 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