Friday, February 01, 2019

Re: [ports-gcc] Unbreak x11/grantlee

On Wed, 30 Jan 2019 13:31:26 +0100
Jeremie Courreges-Anglas <jca@wxcvbn.org> wrote:

> Could this error be triggered by the fact that those undefined symbols
> are to be found in a .a archive which is linked into a .so?
> (--no-undefined shouldn't error out with missing symbols in a .so)

The error comes from libgcc.a. I can now trigger the error in my
amd64 vm without grantlee's .o files, but with the snapshot packages
of g++-4.9.4p15 and qt4-4.8.7p18:

opa$ eg++ -Wl,--no-undefined -shared -o my.so \
> /usr/local/lib/qt4/libQtCore.so.9.0 -lc
ld: error: undefined symbol: pthread_cancel
>>> referenced by gthr-default.h:698 (./gthr-default.h:698)
>>> unwind-dw2.o:(uw_init_context_1) in archive /usr/local/lib/gcc
/x86_64-unknown-openbsd6.4/4.9.4/libgcc.a
...

Most libraries other than QtCore don't cause the error. I observe
that QtCore has undefined _Unwind_Resume and pthread_cancel:

opa$ nm /usr/local/lib/qt4/libQtCore.so.9.0 | egrep 'Unwind|pthread_cancel'
U _Unwind_Resume
U pthread_cancel

I can build a shared object one.so with these undefined symbols, and
use one.so trigger the error. QtCore for amd64 was built with
base-clang; I will build one.so with ports-gcc, to prevent problems
between clang's libc++ and gcc's libestdc++.

ports-gcc would define _Unwind_Resume by linking libgcc.a into one.so.
I use eg++ -nostdlib to remove libgcc.a from the link, so
_Unwind_Resume is undefined, like in QtCore.

Here is the error in amd64 with g++-4.9.4p15, LLD 7.0.1:

opa$ cat one.cc
#include <pthread.h>
void one(pthread_t x) {
try {pthread_cancel(x);} catch(int) {}
}
opa$ eg++ -nostdlib -shared -o one.so one.cc -lpthread
opa$ eg++ -Wl,--no-undefined -shared -o two.so one.so -lc
ld: error: undefined symbol: pthread_cancel
>>> referenced by gthr-default.h:698 (./gthr-default.h:698)
>>> unwind-dw2.o:(uw_init_context_1) in archive /usr/local/lib/gcc
/x86_64-unknown-openbsd6.4/4.9.4/libgcc.a
...

Here is the error in macppc with g++-8.2.0p0, GNU ld 2.17:

ghostborough$ cat one.cc
#include <pthread.h>
void one(pthread_t x) {
try {pthread_cancel(x);} catch(int) {}
}
ghostborough$ eg++ -nostdlib -shared -o one.so one.cc -lpthread
ghostborough$ eg++ -Wl,--no-undefined -shared -o two.so one.so -lc
/usr/local/lib/gcc/powerpc-unknown-openbsd6.4/8.2.0/libgcc.a(unwind-dw2.o):(.got
2+0x18): undefined reference to `pthread_cancel'
/usr/local/lib/gcc/powerpc-unknown-openbsd6.4/8.2.0/libgcc.a(unwind-dw2-fde-dip.
o):(.got2+0x2c): undefined reference to `pthread_cancel'
collect2: error: ld returned 1 exit status



If I use -Wl,--no-undefined in OpenBSD, I must use -lc to prevent
errors with undefined libc symbols. Other systems like Linux and
NetBSD seem to do -lc by default. You can observe that most shared
objects in OpenBSD don't have libc in DT_NEEDED, but other systems
do have libc there.

libedit in OpenBSD/macppc:
ghostborough$ readelf -d /usr/lib/libedit.so.5.2 | grep NEED
0x00000001 (NEEDED) Shared library: [libcurses.so.14.0]

libedit in NetBSD/macppc:
nep$ readelf -d /usr/lib/libedit.so.3.1 | grep NEED
0x00000001 (NEEDED) Shared library: [libterminfo.so.1]
0x00000001 (NEEDED) Shared library: [libc.so.12]

libstdc++ in Alpine Linux:
lia:~$ readelf -d /usr/lib/libstdc++.so.6 | grep NEEDED
0x0000000000000001 (NEEDED) Shared library: [libc.musl-x86_64.so.1]
0x0000000000000001 (NEEDED) Shared library: [libgcc_s.so.1]

--
George Koehler <kernigh@gmail.com>

No comments:

Post a Comment