* [Buildroot] [PATCH] autossh: honour LDFLAGS @ 2016-11-25 18:00 Waldemar Brodkorb 2016-11-28 21:28 ` Thomas Petazzoni 0 siblings, 1 reply; 13+ messages in thread From: Waldemar Brodkorb @ 2016-11-25 18:00 UTC (permalink / raw) To: buildroot Fixes: http://autobuild.buildroot.net/results/08a458572a2e9c599dd32b837b1e5c02a6721973 Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> --- It is indeed a change from uClibc-ng 1.0.18 and upward, but I think it is the fault of the package not respecting LDFLAGS and so not passing -static. I am unsure why it just worked in the past. When it fails linker is doing following: -lnsl -lgcc -lc -lgcc When -static is used, following is passed: -lnsl --start-group -lgcc -lc --end-group The gcc -dumpspecs from both gcc's are the same. I have no idea why gcc behaves in another way when toolchain is compiled with 1.0.17. --- package/autossh/0001-honour-LDFLAGS.patch | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 package/autossh/0001-honour-LDFLAGS.patch diff --git a/package/autossh/0001-honour-LDFLAGS.patch b/package/autossh/0001-honour-LDFLAGS.patch new file mode 100644 index 0000000..2e6160b --- /dev/null +++ b/package/autossh/0001-honour-LDFLAGS.patch @@ -0,0 +1,16 @@ +Honour LDFLAGS, especially required when static linking + +Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> + +diff -Nur autossh-1.4e.orig/Makefile.in autossh-1.4e/Makefile.in +--- autossh-1.4e.orig/Makefile.in 2015-02-10 05:41:58.000000000 +0100 ++++ autossh-1.4e/Makefile.in 2016-11-25 12:49:06.052122855 +0100 +@@ -31,7 +31,7 @@ + + + $(TARGET): $(OFILES) +- $(CC) $(CPPFLAGS) -o $(TARGET) $(OFILES) $(LIBS) ++ $(CC) $(CPPFLAGS) $(LDFLAGS) -o $(TARGET) $(OFILES) $(LIBS) + + clean: + - /bin/rm -f *.o *.a *.core *~ -- 2.1.4 ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-25 18:00 [Buildroot] [PATCH] autossh: honour LDFLAGS Waldemar Brodkorb @ 2016-11-28 21:28 ` Thomas Petazzoni 2016-11-28 23:22 ` Max Filippov 2016-11-29 4:16 ` Waldemar Brodkorb 0 siblings, 2 replies; 13+ messages in thread From: Thomas Petazzoni @ 2016-11-28 21:28 UTC (permalink / raw) To: buildroot Hello, On Fri, 25 Nov 2016 19:00:16 +0100, Waldemar Brodkorb wrote: > Fixes: > http://autobuild.buildroot.net/results/08a458572a2e9c599dd32b837b1e5c02a6721973 > > Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> > --- > It is indeed a change from uClibc-ng 1.0.18 and upward, but I think > it is the fault of the package not respecting LDFLAGS and so not > passing -static. I am unsure why it just worked in the past. > When it fails linker is doing following: > -lnsl -lgcc -lc -lgcc > When -static is used, following is passed: > -lnsl --start-group -lgcc -lc --end-group Applied to master. The difference in the gcc behavior is due to gcc/config/gnu-user.h: #define LINK_GCC_C_SEQUENCE_SPEC \ "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" So, when you're linking dynamic, you have: -lgcc -lc -lgcc And when you're linking statically, you have: --start-group -lgcc -lc --end-group The --start-group/--end-group ask the linker to loop between -lgcc and -lc until all unresolved symbols have been resolved. So dl_iterate_phdr() being defined in the C library, but used in libgcc, I guess the dynamic way (-lgcc -lc -lgcc) doesn't work. However, this interestingly doesn't happen for other architectures such as ARM. Maybe dl_iterate_phdr is not used? In any case, could you try to send your patch upstream to the autossh developers? Thanks! Thomas -- Thomas Petazzoni, CTO, Free Electrons Embedded Linux, Kernel and Android engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-28 21:28 ` Thomas Petazzoni @ 2016-11-28 23:22 ` Max Filippov 2016-11-29 4:16 ` Waldemar Brodkorb 1 sibling, 0 replies; 13+ messages in thread From: Max Filippov @ 2016-11-28 23:22 UTC (permalink / raw) To: buildroot On Mon, Nov 28, 2016 at 1:28 PM, Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote: > On Fri, 25 Nov 2016 19:00:16 +0100, Waldemar Brodkorb wrote: >> Fixes: >> http://autobuild.buildroot.net/results/08a458572a2e9c599dd32b837b1e5c02a6721973 >> >> Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> >> --- >> It is indeed a change from uClibc-ng 1.0.18 and upward, but I think >> it is the fault of the package not respecting LDFLAGS and so not >> passing -static. I am unsure why it just worked in the past. >> When it fails linker is doing following: >> -lnsl -lgcc -lc -lgcc >> When -static is used, following is passed: >> -lnsl --start-group -lgcc -lc --end-group > > Applied to master. > > The difference in the gcc behavior is due to gcc/config/gnu-user.h: > > #define LINK_GCC_C_SEQUENCE_SPEC \ > "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" > > So, when you're linking dynamic, you have: > > -lgcc -lc -lgcc > > And when you're linking statically, you have: > > --start-group -lgcc -lc --end-group > > The --start-group/--end-group ask the linker to loop between -lgcc and > -lc until all unresolved symbols have been resolved. So > dl_iterate_phdr() being defined in the C library, but used in libgcc, I > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. > > However, this interestingly doesn't happen for other architectures such > as ARM. Maybe dl_iterate_phdr is not used? ARM libgcc has its own custom unwinder: unwind-arm.c, which doesn't reference dl_iteratre_phdr, and it doesn't use unwind-dw2-fde-dip.c, which does. But it is reproducible with MIPS. -- Thanks. -- Max ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-28 21:28 ` Thomas Petazzoni 2016-11-28 23:22 ` Max Filippov @ 2016-11-29 4:16 ` Waldemar Brodkorb 2016-11-29 8:43 ` Thomas Petazzoni 1 sibling, 1 reply; 13+ messages in thread From: Waldemar Brodkorb @ 2016-11-29 4:16 UTC (permalink / raw) To: buildroot Hi Thomas, Thomas Petazzoni wrote, > Hello, > > On Fri, 25 Nov 2016 19:00:16 +0100, Waldemar Brodkorb wrote: > > Fixes: > > http://autobuild.buildroot.net/results/08a458572a2e9c599dd32b837b1e5c02a6721973 > > > > Signed-off-by: Waldemar Brodkorb <wbx@openadk.org> > > --- > > It is indeed a change from uClibc-ng 1.0.18 and upward, but I think > > it is the fault of the package not respecting LDFLAGS and so not > > passing -static. I am unsure why it just worked in the past. > > When it fails linker is doing following: > > -lnsl -lgcc -lc -lgcc > > When -static is used, following is passed: > > -lnsl --start-group -lgcc -lc --end-group > > Applied to master. > > The difference in the gcc behavior is due to gcc/config/gnu-user.h: > > #define LINK_GCC_C_SEQUENCE_SPEC \ > "%{static:--start-group} %G %L %{static:--end-group}%{!static:%G}" > > So, when you're linking dynamic, you have: > > -lgcc -lc -lgcc > > And when you're linking statically, you have: > > --start-group -lgcc -lc --end-group > > The --start-group/--end-group ask the linker to loop between -lgcc and > -lc until all unresolved symbols have been resolved. So > dl_iterate_phdr() being defined in the C library, but used in libgcc, I > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. But why gcc behaves different? BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required BR+gcc5+musl+static - no extra -static in LDFLAGS required BR+gcc5+uClibc-ng-1.0.19 - extra -static required! > In any case, could you try to send your patch upstream to the autossh > developers? Already done. best regards Waldemar ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-29 4:16 ` Waldemar Brodkorb @ 2016-11-29 8:43 ` Thomas Petazzoni 2016-11-29 22:50 ` Max Filippov 0 siblings, 1 reply; 13+ messages in thread From: Thomas Petazzoni @ 2016-11-29 8:43 UTC (permalink / raw) To: buildroot Hello, On Tue, 29 Nov 2016 05:16:55 +0100, Waldemar Brodkorb wrote: > > The --start-group/--end-group ask the linker to loop between -lgcc and > > -lc until all unresolved symbols have been resolved. So > > dl_iterate_phdr() being defined in the C library, but used in libgcc, I > > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. > > But why gcc behaves different? > BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required > BR+gcc5+musl+static - no extra -static in LDFLAGS required > BR+gcc5+uClibc-ng-1.0.19 - extra -static required! I would suspect it's a fallout of the "merge everything in libc" change, but I really can't figure out why that would make a difference. Could it be that with older uClibc versions, gcc was not finding the dl_iterate_phdr symbol in uClibc, and therefore disabling the unwind code, and now, due to a change in uClibc, gcc sees the dl_iterate_phdr symbol, enables unwinding support, which cause this extra reference from libgcc to libc? You would have to compare the config.log of libgcc for BR+gcc5+uClibc-ng-1.0.17 and BR+gcc5+uClibc-ng-1.0.19 to see what's the difference. Thomas -- Thomas Petazzoni, CTO, Free Electrons Embedded Linux and Kernel engineering http://free-electrons.com ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-29 8:43 ` Thomas Petazzoni @ 2016-11-29 22:50 ` Max Filippov 2016-11-30 5:00 ` Waldemar Brodkorb 0 siblings, 1 reply; 13+ messages in thread From: Max Filippov @ 2016-11-29 22:50 UTC (permalink / raw) To: buildroot On Tue, Nov 29, 2016 at 12:43 AM, Thomas Petazzoni <thomas.petazzoni@free-electrons.com> wrote: > On Tue, 29 Nov 2016 05:16:55 +0100, Waldemar Brodkorb wrote: >> > The --start-group/--end-group ask the linker to loop between -lgcc and >> > -lc until all unresolved symbols have been resolved. So >> > dl_iterate_phdr() being defined in the C library, but used in libgcc, I >> > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. >> >> But why gcc behaves different? >> BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required >> BR+gcc5+musl+static - no extra -static in LDFLAGS required >> BR+gcc5+uClibc-ng-1.0.19 - extra -static required! > > I would suspect it's a fallout of the "merge everything in libc" > change, but I really can't figure out why that would make a difference. > > Could it be that with older uClibc versions, gcc was not finding the > dl_iterate_phdr symbol in uClibc, and therefore disabling the unwind > code, and now, due to a change in uClibc, gcc sees the dl_iterate_phdr > symbol, enables unwinding support, which cause this extra reference > from libgcc to libc? No. The difference is in the __pthread_initialize_minimal function. Prior to uclibc-1.0.18 release it used to work because a call to __pthread_initialize_minimal from __uClibc_init was resolved to a function defined in libpthread/nptl/sysdeps/generic/libc-tls.c which didn't reference pthread_unwind. Now it is resolved to a function from libpthread/linuxthreads/pthread.c, and that file pulls in other unused functions, which reference __GI___pthread_unwind, and all the way down to the dl_iterate_phdr. More details: http://lists.busybox.net/pipermail/buildroot/2016-November/177477.html -- Thanks. -- Max ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-29 22:50 ` Max Filippov @ 2016-11-30 5:00 ` Waldemar Brodkorb 2016-12-01 18:20 ` Waldemar Brodkorb 2016-12-02 5:12 ` Max Filippov 0 siblings, 2 replies; 13+ messages in thread From: Waldemar Brodkorb @ 2016-11-30 5:00 UTC (permalink / raw) To: buildroot Hi Max, Max Filippov wrote, > On Tue, Nov 29, 2016 at 12:43 AM, Thomas Petazzoni > <thomas.petazzoni@free-electrons.com> wrote: > > On Tue, 29 Nov 2016 05:16:55 +0100, Waldemar Brodkorb wrote: > >> > The --start-group/--end-group ask the linker to loop between -lgcc and > >> > -lc until all unresolved symbols have been resolved. So > >> > dl_iterate_phdr() being defined in the C library, but used in libgcc, I > >> > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. > >> > >> But why gcc behaves different? > >> BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required > >> BR+gcc5+musl+static - no extra -static in LDFLAGS required > >> BR+gcc5+uClibc-ng-1.0.19 - extra -static required! > > > > I would suspect it's a fallout of the "merge everything in libc" > > change, but I really can't figure out why that would make a difference. > > > > Could it be that with older uClibc versions, gcc was not finding the > > dl_iterate_phdr symbol in uClibc, and therefore disabling the unwind > > code, and now, due to a change in uClibc, gcc sees the dl_iterate_phdr > > symbol, enables unwinding support, which cause this extra reference > > from libgcc to libc? > > No. The difference is in the __pthread_initialize_minimal function. > Prior to uclibc-1.0.18 release it used to work because a call to > __pthread_initialize_minimal from __uClibc_init was resolved to > a function defined in libpthread/nptl/sysdeps/generic/libc-tls.c > which didn't reference pthread_unwind. > Now it is resolved to a function from > libpthread/linuxthreads/pthread.c, and that file pulls in other > unused functions, which reference __GI___pthread_unwind, > and all the way down to the dl_iterate_phdr. > > More details: > http://lists.busybox.net/pipermail/buildroot/2016-November/177477.html Sorry that I didn't looked into your report in more detail last time. May be I was too confused ;) I really can't imagine that any code from libpthread/linuxthreads can be involved when we compile Xtensa with NPTL support. I believe there is a bug or a change in behavior regarding static linking prior to 1.0.18. See: wbx at helium:~/buildroot/output/build/uclibc-1.0.19 $ grep -r __pthread_initialize_minimal * Binary file lib/libc.a matches Binary file libc/misc/internals/__uClibc_main.os matches libc/misc/internals/__uClibc_main.c:extern void weak_function __pthread_initialize_minimal(void); libc/misc/internals/__uClibc_main.c:extern void __pthread_initialize_minimal(void); libc/misc/internals/__uClibc_main.c: * __pthread_initialize_minimal so we can use pthread_locks libc/misc/internals/__uClibc_main.c: if (likely(__pthread_initialize_minimal!=NULL)) libc/misc/internals/__uClibc_main.c: __pthread_initialize_minimal(); libpthread/nptl_db/td_ta_thr_iter.c: /* __pthread_initialize_minimal has not run. There is just the main libpthread/nptl_db/td_ta_map_lwp2thr.c: before __pthread_initialize_minimal has gotten far enough. They libpthread/nptl_db/td_thr_validate.c: /* __pthread_initialize_minimal has not run yet. libpthread/linuxthreads/internals.h:void __pthread_initialize_minimal (void); libpthread/linuxthreads/pthread.c:void __pthread_initialize_minimal(void) libpthread/nptl/init.c:void __pthread_initialize_minimal_internal (void) attribute_hidden; libpthread/nptl/init.c:__pthread_initialize_minimal_internal (void) libpthread/nptl/init.c:strong_alias (__pthread_initialize_minimal_internal, libpthread/nptl/init.c: __pthread_initialize_minimal) libpthread/nptl/allocatestack.c: initialize this, since it's done in __pthread_initialize_minimal. */ libpthread/nptl/sysdeps/generic/libc-tls.c:extern void __pthread_initialize_minimal(void) __attribute__((weak)); libpthread/nptl/sysdeps/generic/libc-tls.c:__pthread_initialize_minimal (void) libpthread/nptl/sysdeps/generic/libc-tls.c:__pthread_initialize_minimal (void) libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c: bsr $26, __pthread_initialize_minimal_internal !samegp \n\ Binary file libpthread/nptl/sysdeps/xtensa/libc-tls.os matches Binary file libpthread/nptl/init.os matches Binary file utils/getconf matches libpthread/nptl/sysdeps/xtensa/libc-tls.c includes libpthread/nptl/sysdeps/generic/libc-tls.c. Prior to 1.0.18 libpthread.so was linked with special LDFLAGS: LDFLAGS-libpthread.so += $(top_builddir)lib/$(UCLIBC_LDSO_NAME)-$(VERSION).so $(top_builddir)lib/libdl-$(VERSION).so \ -Wl,-z,nodelete,-z,initfirst,-init=$(SYMBOL_PREFIX)__pthread_initialize_minimal_internal May be this might be a reason we see different behavior. best regards Waldemar ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-30 5:00 ` Waldemar Brodkorb @ 2016-12-01 18:20 ` Waldemar Brodkorb 2016-12-02 5:12 ` Max Filippov 1 sibling, 0 replies; 13+ messages in thread From: Waldemar Brodkorb @ 2016-12-01 18:20 UTC (permalink / raw) To: buildroot Hi, Waldemar Brodkorb wrote, > Hi Max, > Max Filippov wrote, > > > On Tue, Nov 29, 2016 at 12:43 AM, Thomas Petazzoni > > <thomas.petazzoni@free-electrons.com> wrote: > > > On Tue, 29 Nov 2016 05:16:55 +0100, Waldemar Brodkorb wrote: > > >> > The --start-group/--end-group ask the linker to loop between -lgcc and > > >> > -lc until all unresolved symbols have been resolved. So > > >> > dl_iterate_phdr() being defined in the C library, but used in libgcc, I > > >> > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. > > >> > > >> But why gcc behaves different? > > >> BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required > > >> BR+gcc5+musl+static - no extra -static in LDFLAGS required > > >> BR+gcc5+uClibc-ng-1.0.19 - extra -static required! > > > > > > I would suspect it's a fallout of the "merge everything in libc" > > > change, but I really can't figure out why that would make a difference. > > > > > > Could it be that with older uClibc versions, gcc was not finding the > > > dl_iterate_phdr symbol in uClibc, and therefore disabling the unwind > > > code, and now, due to a change in uClibc, gcc sees the dl_iterate_phdr > > > symbol, enables unwinding support, which cause this extra reference > > > from libgcc to libc? > > > > No. The difference is in the __pthread_initialize_minimal function. > > Prior to uclibc-1.0.18 release it used to work because a call to > > __pthread_initialize_minimal from __uClibc_init was resolved to > > a function defined in libpthread/nptl/sysdeps/generic/libc-tls.c > > which didn't reference pthread_unwind. > > Now it is resolved to a function from > > libpthread/linuxthreads/pthread.c, and that file pulls in other > > unused functions, which reference __GI___pthread_unwind, > > and all the way down to the dl_iterate_phdr. > > > > More details: > > http://lists.busybox.net/pipermail/buildroot/2016-November/177477.html > > Sorry that I didn't looked into your report in more detail last time. > May be I was too confused ;) > > I really can't imagine that any code from libpthread/linuxthreads > can be involved when we compile Xtensa with NPTL support. > > I believe there is a bug or a change in behavior regarding static > linking prior to 1.0.18. > > See: > wbx at helium:~/buildroot/output/build/uclibc-1.0.19 $ grep -r __pthread_initialize_minimal * > Binary file lib/libc.a matches > Binary file libc/misc/internals/__uClibc_main.os matches > libc/misc/internals/__uClibc_main.c:extern void weak_function __pthread_initialize_minimal(void); > libc/misc/internals/__uClibc_main.c:extern void __pthread_initialize_minimal(void); > libc/misc/internals/__uClibc_main.c: * __pthread_initialize_minimal so we can use pthread_locks > libc/misc/internals/__uClibc_main.c: if (likely(__pthread_initialize_minimal!=NULL)) > libc/misc/internals/__uClibc_main.c: __pthread_initialize_minimal(); > libpthread/nptl_db/td_ta_thr_iter.c: /* __pthread_initialize_minimal has not run. There is just the main > libpthread/nptl_db/td_ta_map_lwp2thr.c: before __pthread_initialize_minimal has gotten far enough. They > libpthread/nptl_db/td_thr_validate.c: /* __pthread_initialize_minimal has not run yet. > libpthread/linuxthreads/internals.h:void __pthread_initialize_minimal (void); > libpthread/linuxthreads/pthread.c:void __pthread_initialize_minimal(void) > libpthread/nptl/init.c:void __pthread_initialize_minimal_internal (void) attribute_hidden; > libpthread/nptl/init.c:__pthread_initialize_minimal_internal (void) > libpthread/nptl/init.c:strong_alias (__pthread_initialize_minimal_internal, > libpthread/nptl/init.c: __pthread_initialize_minimal) > libpthread/nptl/allocatestack.c: initialize this, since it's done in __pthread_initialize_minimal. */ > libpthread/nptl/sysdeps/generic/libc-tls.c:extern void __pthread_initialize_minimal(void) __attribute__((weak)); > libpthread/nptl/sysdeps/generic/libc-tls.c:__pthread_initialize_minimal (void) > libpthread/nptl/sysdeps/generic/libc-tls.c:__pthread_initialize_minimal (void) > libpthread/nptl/sysdeps/alpha/elf/pt-initfini.c: bsr $26, __pthread_initialize_minimal_internal !samegp \n\ > Binary file libpthread/nptl/sysdeps/xtensa/libc-tls.os matches > Binary file libpthread/nptl/init.os matches > Binary file utils/getconf matches > > libpthread/nptl/sysdeps/xtensa/libc-tls.c includes > libpthread/nptl/sysdeps/generic/libc-tls.c. > > Prior to 1.0.18 libpthread.so was linked with special LDFLAGS: > LDFLAGS-libpthread.so += > $(top_builddir)lib/$(UCLIBC_LDSO_NAME)-$(VERSION).so > $(top_builddir)lib/libdl-$(VERSION).so \ > -Wl,-z,nodelete,-z,initfirst,-init=$(SYMBOL_PREFIX)__pthread_initialize_minimal_internal > > May be this might be a reason we see different behavior. I think it is not the reason. I think it is just how pthread_cancel and some other code in NPTL is implemented. There is some circular dependency we can't change after we have integrated all the code in libc.a. Musl does not use any functionality from libgcc, so it has not the problem with the static linking issues we are seeing. So as long as we have the pthread_cancel code which use libgcc internally, we can't avoid any breakage from packages not correctly passing -static while linking. If anyone thinks the analysis is wrong, please speak up. best regards Waldemar ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-11-30 5:00 ` Waldemar Brodkorb 2016-12-01 18:20 ` Waldemar Brodkorb @ 2016-12-02 5:12 ` Max Filippov 2016-12-02 5:25 ` Waldemar Brodkorb 1 sibling, 1 reply; 13+ messages in thread From: Max Filippov @ 2016-12-02 5:12 UTC (permalink / raw) To: buildroot Hello, TL;DR: -static is good, order of objects in libc.a is important. On Tue, Nov 29, 2016 at 9:00 PM, Waldemar Brodkorb <wbx@openadk.org> wrote: >> On Tue, Nov 29, 2016 at 12:43 AM, Thomas Petazzoni >> <thomas.petazzoni@free-electrons.com> wrote: >> > On Tue, 29 Nov 2016 05:16:55 +0100, Waldemar Brodkorb wrote: >> >> > The --start-group/--end-group ask the linker to loop between -lgcc and >> >> > -lc until all unresolved symbols have been resolved. So >> >> > dl_iterate_phdr() being defined in the C library, but used in libgcc, I >> >> > guess the dynamic way (-lgcc -lc -lgcc) doesn't work. >> >> >> >> But why gcc behaves different? >> >> BR+gcc5+uClibc-ng-1.0.17 - no extra -static in LDFLAGS required >> >> BR+gcc5+musl+static - no extra -static in LDFLAGS required >> >> BR+gcc5+uClibc-ng-1.0.19 - extra -static required! >> > >> > I would suspect it's a fallout of the "merge everything in libc" >> > change, but I really can't figure out why that would make a difference. >> > >> > Could it be that with older uClibc versions, gcc was not finding the >> > dl_iterate_phdr symbol in uClibc, and therefore disabling the unwind >> > code, and now, due to a change in uClibc, gcc sees the dl_iterate_phdr >> > symbol, enables unwinding support, which cause this extra reference >> > from libgcc to libc? >> >> No. The difference is in the __pthread_initialize_minimal function. >> Prior to uclibc-1.0.18 release it used to work because a call to >> __pthread_initialize_minimal from __uClibc_init was resolved to >> a function defined in libpthread/nptl/sysdeps/generic/libc-tls.c >> which didn't reference pthread_unwind. >> Now it is resolved to a function from >> libpthread/linuxthreads/pthread.c, and that file pulls in other >> unused functions, which reference __GI___pthread_unwind, >> and all the way down to the dl_iterate_phdr. >> >> More details: >> http://lists.busybox.net/pipermail/buildroot/2016-November/177477.html > > Sorry that I didn't looked into your report in more detail last time. > May be I was too confused ;) > > I really can't imagine that any code from libpthread/linuxthreads > can be involved when we compile Xtensa with NPTL support. Oops, wrong path, wrong searching tool. But the idea: in the failing case __pthread_initialize_minimal is taken from libpthread/nptl/init.c and it's way bigger than __pthread_initialize_minimal used for linking with the uClibc-ng-1.0.17. Now, I believe that adding the missing -static is the right solution, because even with uClibc-ng-1.0.17 the linking fails for a simple application that uses pthread: $ cat hello.c #include <pthread.h> int main() { pthread_create(NULL, NULL, NULL, NULL); return 0; } $ xtensa-buildroot-linux-uclibc-gcc -pthread hello.c -o hello .../libgcc.a(unwind-dw2-fde-dip.o): In function `__gthread_mutex_lock': .../gthr-default.h:748: undefined reference to `dl_iterate_phdr' collect2: error: ld returned 1 exit status The only thing that worries me at this point is that now we have a lot of pthread internals linked into the program image even when the program doesn't use them. E.g. autossh built with uClibc-ng-1.0.17: $ size -A autossh autossh: section size addr .text 63771 4194484 .rodata 28112 4258256 .eh_frame 792 4286368 .tbss 8 4291256 .ctors 8 4291256 .dtors 8 4291264 .jcr 4 4291272 .data.rel.ro 160 4291276 .data 692 4291440 .bss 15524 4292136 .comment 31 0 .xtensa.info 56 0 .debug_aranges 288 0 .debug_info 2195 0 .debug_abbrev 398 0 .debug_line 6327 0 .debug_frame 40 0 .debug_str 468 0 .debug_loc 40 0 .xt.lit 3752 0 .xt.prop 58596 0 Total 181270 $ nm autossh | grep pthread | wc -l 10 vs. autossh built with uClibc-ng-1.0.19: $ size -A autossh autossh: section size addr .text 83955 4194484 .rodata 28564 4278440 .eh_frame 1628 4307004 .tdata 4 4312728 .tbss 8 4312732 .ctors 8 4312732 .dtors 8 4312740 .jcr 4 4312748 .data.rel.ro 160 4312752 .data 736 4312912 .bss 24516 4313648 .comment 35 0 .xtensa.info 56 0 .debug_aranges 384 0 .debug_info 20096 0 .debug_abbrev 2925 0 .debug_line 14492 0 .debug_frame 1432 0 .debug_str 4789 0 .debug_loc 11212 0 .debug_ranges 608 0 .xt.lit 4384 0 .xt.prop 77364 0 Total 277368 $ nm autossh | grep pthread | wc -l 77 That makes me wonder, how pthread initialization is done in uClibc-ng-1.0.17 for applications that use pthread and that don't. So what I see is the following: - an application that uses pthread_create references libpthread/nptl/init.c (because pthread_create.c includes allocatestack.c, which references __xidcmd defined in init.c from its __nptl_setxid) and thus gets __pthread_initialize_minimal from it. - an application that doesn't use pthread_create gets its weakly defined __pthread_initialize_minimal from the libpthread/nptl/sysdeps/generic/libc-tls.c, which provides __libc_setup_tls referenced from the __uClibc_init. So we're interested in the following three files: - init.os (built from libpthread/nptl/init.c, with strong __pthread_initialize_minimal) - libc-tls.os (built from libpthread/nptl/sysdeps/xtensa/libc-tls.c, with weak __pthread_initialize_minimal) - __uClibc_main.os (built from libc/misc/internal/__uClibc_main.c with undefined reference to __pthread_initialize_minimal). Comparing uClibc-ng-1.0.17 with uClibc-ng-1.0.19 I see the following: 1.0.17 had libc.a with libc-tls.os and __uClibc_main.os and libpthread.a with init.os. 1.0.19 has libc.a with libc-tls.os, __uClibc_main.os and init.os in it in that order. I haven't found any related documentation, but apparently with 1.0.19 when a definition of __pthread_initialize_minimal is searched for the undefined symbol in __uClibc_main.os, the init.os is considered first. Manually removing and re-adding libc-tls.os and init.os so that the final order is __uClibc_main.os, libc-tls.os and init.os restores the 1.0.17 behavior. > Prior to 1.0.18 libpthread.so was linked with special LDFLAGS: > LDFLAGS-libpthread.so += > $(top_builddir)lib/$(UCLIBC_LDSO_NAME)-$(VERSION).so > $(top_builddir)lib/libdl-$(VERSION).so \ > -Wl,-z,nodelete,-z,initfirst,-init=$(SYMBOL_PREFIX)__pthread_initialize_minimal_internal > > May be this might be a reason we see different behavior. AFAICS it only affects shared library, i.e. not related to static linking case. -- Thanks. -- Max ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-12-02 5:12 ` Max Filippov @ 2016-12-02 5:25 ` Waldemar Brodkorb 2016-12-03 2:12 ` Max Filippov 0 siblings, 1 reply; 13+ messages in thread From: Waldemar Brodkorb @ 2016-12-02 5:25 UTC (permalink / raw) To: buildroot Hi Max, Max Filippov wrote, > Hello, > > TL;DR: -static is good, order of objects in libc.a is important. Thanks for the very detailed analysis. Do you have any idea how we could restore the old order and keep the binaries smaller? best regards Waldemar ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-12-02 5:25 ` Waldemar Brodkorb @ 2016-12-03 2:12 ` Max Filippov 2016-12-04 12:06 ` Waldemar Brodkorb 0 siblings, 1 reply; 13+ messages in thread From: Max Filippov @ 2016-12-03 2:12 UTC (permalink / raw) To: buildroot On Thu, Dec 1, 2016 at 9:25 PM, Waldemar Brodkorb <wbx@openadk.org> wrote: >> Hello, >> >> TL;DR: -static is good, order of objects in libc.a is important. > > Thanks for the very detailed analysis. > Do you have any idea how we could restore the old order and keep > the binaries smaller? One ugly solution could be putting __uClibc-main.os before both libc-tls.os and init.os, something like the following: diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in index ae094ee..d2400d2 100644 --- a/libc/misc/internals/Makefile.in +++ b/libc/misc/internals/Makefile.in @@ -25,7 +25,7 @@ libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS else libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.os endif -libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o +libc-static-y := $(MISC_INTERNALS_OUT)/__uClibc_main.o $(libc-static-y) libc-static-$(UCLIBC_FORMAT_FLAT_SEP_DATA) += \ $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \ $(MISC_INTERNALS_OUT)/shared_flat_add_library.o -- Thanks. -- Max ^ permalink raw reply related [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-12-03 2:12 ` Max Filippov @ 2016-12-04 12:06 ` Waldemar Brodkorb 2016-12-05 3:24 ` Max Filippov 0 siblings, 1 reply; 13+ messages in thread From: Waldemar Brodkorb @ 2016-12-04 12:06 UTC (permalink / raw) To: buildroot Hi Max, Max Filippov wrote, > On Thu, Dec 1, 2016 at 9:25 PM, Waldemar Brodkorb <wbx@openadk.org> wrote: > >> Hello, > >> > >> TL;DR: -static is good, order of objects in libc.a is important. > > > > Thanks for the very detailed analysis. > > Do you have any idea how we could restore the old order and keep > > the binaries smaller? > > One ugly solution could be putting __uClibc-main.os before both libc-tls.os > and init.os, something like the following: > > diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in > index ae094ee..d2400d2 100644 > --- a/libc/misc/internals/Makefile.in > +++ b/libc/misc/internals/Makefile.in > @@ -25,7 +25,7 @@ libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS > else > libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.os > endif > -libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o > +libc-static-y := $(MISC_INTERNALS_OUT)/__uClibc_main.o $(libc-static-y) > libc-static-$(UCLIBC_FORMAT_FLAT_SEP_DATA) += \ > $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \ > $(MISC_INTERNALS_OUT)/shared_flat_add_library.o > Thanks for the patch, I tried it. But unforunately it breaks other applications as busybox init. Not startup possible in Qemu to test the smaller autossh. best regards Waldemar ^ permalink raw reply [flat|nested] 13+ messages in thread
* [Buildroot] [PATCH] autossh: honour LDFLAGS 2016-12-04 12:06 ` Waldemar Brodkorb @ 2016-12-05 3:24 ` Max Filippov 0 siblings, 0 replies; 13+ messages in thread From: Max Filippov @ 2016-12-05 3:24 UTC (permalink / raw) To: buildroot On Sun, Dec 4, 2016 at 4:06 AM, Waldemar Brodkorb <wbx@openadk.org> wrote: >> On Thu, Dec 1, 2016 at 9:25 PM, Waldemar Brodkorb <wbx@openadk.org> wrote: >> >> Hello, >> >> >> >> TL;DR: -static is good, order of objects in libc.a is important. >> > >> > Thanks for the very detailed analysis. >> > Do you have any idea how we could restore the old order and keep >> > the binaries smaller? >> >> One ugly solution could be putting __uClibc-main.os before both libc-tls.os >> and init.os, something like the following: >> >> diff --git a/libc/misc/internals/Makefile.in b/libc/misc/internals/Makefile.in >> index ae094ee..d2400d2 100644 >> --- a/libc/misc/internals/Makefile.in >> +++ b/libc/misc/internals/Makefile.in >> @@ -25,7 +25,7 @@ libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.oS >> else >> libc-shared-y += $(MISC_INTERNALS_OUT)/__uClibc_main.os >> endif >> -libc-static-y += $(MISC_INTERNALS_OUT)/__uClibc_main.o >> +libc-static-y := $(MISC_INTERNALS_OUT)/__uClibc_main.o $(libc-static-y) >> libc-static-$(UCLIBC_FORMAT_FLAT_SEP_DATA) += \ >> $(MISC_INTERNALS_OUT)/shared_flat_initfini.o \ >> $(MISC_INTERNALS_OUT)/shared_flat_add_library.o > > Thanks for the patch, I tried it. > But unforunately it breaks other applications as busybox init. Well, it shows that the current uClibc-ng is broken without pthread code. The root cause of the init breakage is a call to _pthread_cleanup_push_defer from mallopt, which currently points to NULL, because _pthread_cleanup_push_defer is weak and its definition was removed from __uClibc_main.c in the unification patch. Restoring it fixes init for me. I tried to follow the story of these definitions, but it seems to be a chain of failures and attempted fixes. So I'm not sure this fixes everything and doesn't break something else ): It sure needs testing. diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c index 46e24d8..0446b08 100644 --- a/libc/misc/internals/__uClibc_main.c +++ b/libc/misc/internals/__uClibc_main.c @@ -68,6 +68,42 @@ uintptr_t __stack_chk_guard attribute_relro; void internal_function _dl_aux_init (ElfW(auxv_t) *av); +#ifdef __UCLIBC_HAS_THREADS__ +/* + * uClibc internal locking requires that we have weak aliases + * for dummy functions in case libpthread.a is not linked in. + * This needs to be in compilation unit that is pulled always + * in or linker will disregard these weaks. + */ + +static int __pthread_return_0 (pthread_mutex_t *unused) { return 0; } +weak_alias (__pthread_return_0, __pthread_mutex_lock) +weak_alias (__pthread_return_0, __pthread_mutex_trylock) +weak_alias (__pthread_return_0, __pthread_mutex_unlock) + +int weak_function +__pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) +{ + return 0; +} + +void weak_function +_pthread_cleanup_push_defer(struct _pthread_cleanup_buffer *__buffer, + void (*__routine) (void *), void *__arg) +{ + __buffer->__routine = __routine; + __buffer->__arg = __arg; +} + +void weak_function +_pthread_cleanup_pop_restore(struct _pthread_cleanup_buffer *__buffer, + int __execute) +{ + if (__execute) + __buffer->__routine(__buffer->__arg); +} +#endif /* __UCLIBC_HAS_THREADS__ */ + #endif /* !SHARED */ /* Defeat compiler optimization which assumes function addresses are never NULL */ -- Thanks. -- Max ^ permalink raw reply related [flat|nested] 13+ messages in thread
end of thread, other threads:[~2016-12-05 3:24 UTC | newest] Thread overview: 13+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-11-25 18:00 [Buildroot] [PATCH] autossh: honour LDFLAGS Waldemar Brodkorb 2016-11-28 21:28 ` Thomas Petazzoni 2016-11-28 23:22 ` Max Filippov 2016-11-29 4:16 ` Waldemar Brodkorb 2016-11-29 8:43 ` Thomas Petazzoni 2016-11-29 22:50 ` Max Filippov 2016-11-30 5:00 ` Waldemar Brodkorb 2016-12-01 18:20 ` Waldemar Brodkorb 2016-12-02 5:12 ` Max Filippov 2016-12-02 5:25 ` Waldemar Brodkorb 2016-12-03 2:12 ` Max Filippov 2016-12-04 12:06 ` Waldemar Brodkorb 2016-12-05 3:24 ` Max Filippov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox