public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* static linking + nostartfiles + exceptions
@ 2016-08-09 14:45 d wk
  0 siblings, 0 replies; only message in thread
From: d wk @ 2016-08-09 14:45 UTC (permalink / raw)
  To: gcc-help

Hi there,

I'm trying to replace _start with a custom implementation in my
statically-linked binary on x86_64. I pass -nostartfiles to g++ and
pass in crt1.o, crti.o, crtbegin.o and crtend.o, crtn.o (but with
crt1.o replaced with my own implementation). This works, but I noticed
that C++ exceptions stop working (they are never caught and cause a
SIGABRT).

After some debugging I discovered that the resulting executable does
not have an .eh_frame section. So the issue is resolved by using
-Wl,--eh-frame-hdr. But this doesn't seem to be required by the
manual:
https://gcc.gnu.org/onlinedocs/gcc-4.2.2/gcc/Link-Options.html#index-shared_002dlibgcc-697

Also, using -static-libgcc and -shared-libgcc makes no difference. I
suppose that with static linking, it always uses the static libgcc and
this prevents exceptions from working correctly. It seems strange that
as a user I need to specify -Wl,--eh-frame-hdr to resolve this.
Couldn't this flag be inferred from the combination of -shared-libgcc
and -static? (Since -shared-libgcc is supposed to enable exceptions in
this context.) At least I feel that the documentation should be
updated to mention this case.

Suggestions welcome. See a complete test case below. Also, is there
any easier way of just replacing _start?

Note: this test case is also available right now at
http://elfery.net/files/gcc-eh-test.sh
----
#!/bin/sh
cat >throw.cpp <<EOF
#include <iostream>

int main() {
    try {
        throw "an exception";
    }
    catch(const char *s) {
        std::cout << "caught " << s << " successfully\n";
    }
    return 0;
}
EOF

D=/usr/lib/x86_64-linux-gnu/

STARTFILES="$D/crt1.o $D/crti.o `gcc --print-file-name=crtbegin.o`"
ENDFILES="`gcc --print-file-name=crtend.o` $D/crtn.o"

echo dynamically linked should work...
g++ throw.cpp -o throw -nostartfiles $STARTFILES $ENDFILES
./throw || true
echo

echo statically linked should fail...
g++ -static throw.cpp -o throw -nostartfiles $STARTFILES $ENDFILES
./throw || true
echo

echo statically linked with -shared-libgcc doesn\'t help...
g++ -static throw.cpp -o throw -nostartfiles $STARTFILES $ENDFILES
-shared-libgcc
./throw || true
echo

echo statically linked with -static-libgcc doesn\'t help...
g++ -static throw.cpp -o throw -nostartfiles $STARTFILES $ENDFILES
-static-libgcc
./throw || true
echo

echo but statically linked with -Wl,--eh-frame-hdr works...
g++ -static throw.cpp -o throw -nostartfiles $STARTFILES $ENDFILES
-Wl,--eh-frame-hdr
./throw || true
----
$ ./test.sh
dynamically linked should work...
caught an exception successfully

statically linked should fail...
Aborted

statically linked with -shared-libgcc doesn't help...
Aborted

statically linked with -static-libgcc doesn't help...
Aborted

but statically linked with -Wl,--eh-frame-hdr works...
caught an exception successfully
----

Thanks,

-- dwk

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2016-08-09 14:45 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-09 14:45 static linking + nostartfiles + exceptions d wk

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 read-only IMAP folder(s) and NNTP newsgroup(s).