mailing list of musl libc
 help / color / mirror / code / Atom feed
From: Rich Felker <dalias@aerifal.cx>
To: musl@lists.openwall.com
Subject: Re: static linking and dlopen
Date: Sat, 8 Dec 2012 17:52:37 -0500	[thread overview]
Message-ID: <20121208225237.GV20323@brightrain.aerifal.cx> (raw)
In-Reply-To: <CAKHv7pjDLvW+8vKXi4FzEu6eMA+nX5sOA8Z6-YikGCD8QXzQyw@mail.gmail.com>

On Sat, Dec 08, 2012 at 08:09:35PM +0200, Paul Schutte wrote:
> Hi,
> 
> I have a strong preference towards static linking these days because the
> running program use so much less memory.
> 
> When I link a binary statically and that binary then use dlopen, would that
> work 100% ?

Presently, it does not work at all. At best, it loses all the
advantages of static linking.

> What would open if the shared object that was dlopened want's to call
> functions in other shared libraries ?

Dependencies of any loaded library also get loaded.

> I understand that when using dynamic linking those libraries would just get
> loaded, but I am not sure what would happen with static linking.

With static linking, they would have to be loaded too. This means a
static-linked program using dlopen would have to contain the entire
dynamic linker logic. What's worse, it would also have to contain at
least the entire libc, and if you were using static versions of any
other library in the main program, and a loaded module referenced a
dynamic version of the same library, you'd probably run into
unpredictable crashing when the versions do not match exactly.

The source of all these problems is basically the same as the benefit
of static linking: the fact that the linker resolves, statically at
link time, which object files are needed to satisfy the needs of the
program. With dlopen, however, there is no static answer; *any* object
is potentially-needed, not directly by the main program, but possibly
by loaded modules. Consider what happens now if you only link part of
libc into the main program statically: additional modules loaded at
runtime won't necessarily have all the stuff they need, so dlopen
would also have to load libc.so. But now you're potentially using two
different versions of libc in the same program; if
implementation-internal data structures like FILE or the pthread
structure are not identical between the 2 versions, you'll hit an ABI
incompatibility, despite the fact that these data structures were
intended to be implementation-internal and never affect ABI. Even
without that issue, you have issues like potentially 2 copies of
malloc trying to manage the heap without being aware of one another,
and thus clobbering it.

For libc, the issues are all fixable by making sure that a static
version of dlopen depends on every single function in libc, so that
another copy never needs to get loaded. However, for other static
libraries pulled into the main program, there is really no fix without
help from the linker (it would have to pull in the entire library, and
somehow leave a note for dlopen to see that library is already loaded
and avoid loading it dynamically too).

Note that, even if we could get this working with a reasonable level
of robustness, almost all the advantages of static linking would be
gone. Static-linked programs using dlopen would be huge and ugly.

If you really want to make single-file binaries with no dependencies
and dlopen support, I think the solution is to first build them
dynamically linked, then merge the main program and all .so files into
a single ELF file. I don't know of any tools capable of doing this,
but in principle it's possible to write one. There are at least 2
different approaches to this. One is to process the ELF files and
merge their list of LOAD segments, symbol and relocation tables, etc.
all into a single ELF file, leaving the relocations in place for the
dynamic linker to perform at startup. This would require some
modification to the dynamic linker still. The other approach is the
equivalent of emacs' unexec dumper: place some kind of hook to run
after the dynamic linker loads everything, but before any other
application code runs, which dumps the entire memory space to an ELF
file which, when run, will reconstruct itself.

Rich


  parent reply	other threads:[~2012-12-08 22:52 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-12-08 18:09 Paul Schutte
2012-12-08 20:47 ` Szabolcs Nagy
2012-12-09 20:02   ` Rob Landley
2012-12-08 22:52 ` Rich Felker [this message]
2012-12-08 23:17   ` Charlie Kester
2012-12-08 23:23     ` Rich Felker
2012-12-09  0:04       ` Paul Schutte
2012-12-09  0:16         ` Rich Felker
2012-12-09 15:24           ` Paul Schutte
2012-12-09 17:54             ` Rich Felker
2012-12-09 19:07               ` Szabolcs Nagy
2012-12-09 19:24                 ` Rich Felker
2012-12-09  2:39         ` Szabolcs Nagy
2012-12-09  6:36     ` croco
2012-12-09  7:25       ` Isaac Dunham
2012-12-09  8:10         ` Charlie Kester
2012-12-09 10:08         ` croco
2012-12-09 11:46           ` Szabolcs Nagy
2012-12-09 15:11             ` Rich Felker
2012-12-09 20:43           ` Rob Landley
2012-12-08 23:29   ` Paul Schutte
2012-12-09  2:55   ` Szabolcs Nagy
2012-12-09  3:10     ` Rich Felker
2012-12-09  7:30     ` Isaac Dunham
2012-12-09 20:09   ` Rob Landley
2012-12-09 21:53     ` Rich Felker

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20121208225237.GV20323@brightrain.aerifal.cx \
    --to=dalias@aerifal.cx \
    --cc=musl@lists.openwall.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).