static linking failed with sigaction testing program
This is a follow-up of my previous bug report on static linking failed with sigaction testing program. With 0.9.32-rc3, following testing program failed with static linking on MIPS. The result is same with gcc-4.4.5 and gcc-4.5.2. While my old 0.9.29 uClibc plus gcc-4.4.5 works well. Here is static-test.c #include int main(void) { struct sigaction old, new; sigaction(11, &new, &old); return 3; } $ mipsel-linux-gcc static-test.c -o static-test -static -lpthread /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libc.a(sigaction.os): In function `__libc_sigaction': sigaction.c:(.text+0x0): multiple definition of `__libc_sigaction' /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text+0x0): first defined here /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libc.a(sigaction.os): In function `sigaction': sigaction.c:(.text+0x18): multiple definition of `__sigaction' /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text+0x18): first defined here collect2: ld returned 1 exit status $ mipsel-linux-gcc static-test.c -o static-test -static -lc -lpthread has no problem. The reason is that after sigaction was pulled in from libpthread.a:pt-sigaction.os, another runtime supporting function abort() in libc calls sigaction that will be pulled from libc.a:sigaction.os, and cause multiple definitions. In case that "-static -lc -lpthread", sigaction was pulled from libc.a:sigaction.os to resolve undefined sigaction for both the one called in abort and main already. To fix it, __libc_sigaction and __sigaction should not be GLOBAL in both libc.a and libpthread.a. Here is my patch to fix it. >From a322d80e01137f8d8287ffda716dbff05960cdab Mon Sep 17 00:00:00 2001 From: Jian Peng Date: Fri, 25 Mar 2011 16:12:58 -0700 Subject: [PATCH 1/1] MIPS: sigaction static linking failed With simple sigaction testing program, "mipsel-linux-gcc prog.c -o prog -static -lpthread" failed to compile due to multiple definition error of __libc_sigaction and __sigaction. The problem is that __libc_sigaction and __sigaction should not be GLOBAL in both libc.a and libpthread.a. Signed-off-by: Jian Peng --- libc/sysdeps/linux/mips/sigaction.c | 19 +++ libpthread/nptl/sysdeps/pthread/sigaction.c |3 +-- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/libc/sysdeps/linux/mips/sigaction.c b/libc/sysdeps/linux/mips/sigaction.c index f2d2747..26b816c 100644 --- a/libc/sysdeps/linux/mips/sigaction.c +++ b/libc/sysdeps/linux/mips/sigaction.c @@ -27,8 +27,9 @@ #define SA_RESTORER0x0400 -extern __typeof(sigaction) __libc_sigaction; - +#ifdef NOT_IN_libc +extern __typeof(sigaction) __libc_sigaction; +#endif #ifdef __NR_rt_sigaction @@ -43,7 +44,12 @@ static void restore(void) __asm__ ("__restore"); /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ -int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +#ifdef NOT_IN_libc +int +#else +static int +#endif +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { # if _MIPS_SIM != _ABIO32 struct sigaction kact; @@ -65,7 +71,12 @@ extern void restore(void) __asm__ ("__restore") attribute_hidden; /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ -int __libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) +#ifdef NOT_IN_libc +int +#else +static int +#endif +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction *oact) { int result; struct old_kernel_sigaction kact, koact; diff --git a/libpthread/nptl/sysdeps/pthread/sigaction.c b/libpthread/nptl/sysdeps/pthread/sigaction.c index e004a39..190a3ab 100644 --- a/libpthread/nptl/sysdeps/pthread/sigaction.c +++ b/libpthread/nptl/sysdeps/pthread/sigaction.c @@ -26,8 +26,7 @@ #define LIBC_SIGACTION 1 #include -extern __typeof(sigaction) __sigaction; -int +static int __sigaction (int sig, const struct sigaction *act, struct sigaction *oact) { if (__builtin_expect (sig == SIGCANCEL || sig == SIGSETXID, 0)) -- 1.7.4.1 ___ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc
Re: static linking failed with sigaction testing program
Hi > This is a follow-up of my previous bug report on static linking failed > with sigaction testing program. > > With 0.9.32-rc3, following testing program failed with static linking on > MIPS. The result is same with gcc-4.4.5 and gcc-4.5.2. While my old 0.9.29 > uClibc plus gcc-4.4.5 works well. > > > Here is static-test.c > > #include > > int main(void) > { > struct sigaction old, new; > > sigaction(11, &new, &old); > return 3; > } > > $ mipsel-linux-gcc static-test.c -o static-test -static -lpthread > > /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libc.a(sigaction.os): > In function `__libc_sigaction': > sigaction.c:(.text+0x0): multiple definition of `__libc_sigaction' > /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text+0x0): > > first defined here > /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libc.a(sigaction.os): > In function `sigaction': > sigaction.c:(.text+0x18): multiple definition of `__sigaction' it does not really make sense to use -lpthread but that is another story I assume you are using NPTL as threads, NPTL devs, one of the __sigactions needs probably be weak > > /big/toolchains/stbgcc-4.5.2-0.2/bin/../mipsel-linux-uclibc/sys-root/usr/lib/libpthread.a(pt-sigaction.os):pt-sigaction.c:(.text+0x18): > first defined here > collect2: ld returned 1 exit status > > $ mipsel-linux-gcc static-test.c -o static-test -static -lc -lpthread I would say, do not use that syntax, the compiler defaults should be correct (speak, -lc is added at the end of linking, if any earlier __sigaction was seen in a library provided on command line by -l, libc should provide a weak to not conflict > > has no problem. > > The reason is that after sigaction was pulled in from > libpthread.a:pt-sigaction.os, another runtime supporting function abort() in > libc calls > sigaction that will be pulled from libc.a:sigaction.os, and cause multiple > definitions. > > In case that "-static -lc -lpthread", sigaction was pulled from > libc.a:sigaction.os to resolve undefined sigaction for both the one called in > abort > and main already. > > To fix it, __libc_sigaction and __sigaction should not be GLOBAL in both > libc.a and libpthread.a. To really fix it, we have to get rid of all duplicated *sigactions, only one should stay (preferably in libc IMHO) Peter > > > Here is my patch to fix it. > > >From a322d80e01137f8d8287ffda716dbff05960cdab Mon Sep 17 00:00:00 2001 > From: Jian Peng > Date: Fri, 25 Mar 2011 16:12:58 -0700 > > Subject: [PATCH 1/1] MIPS: sigaction static linking failed > > With simple sigaction testing program, "mipsel-linux-gcc prog.c -o prog > -static -lpthread" failed to compile due to multiple definition error of > __libc_sigaction and __sigaction. > > > The problem is that __libc_sigaction and __sigaction should not be GLOBAL > in both libc.a and libpthread.a. > > Signed-off-by: Jian Peng > --- > > libc/sysdeps/linux/mips/sigaction.c | 19 +++ > libpthread/nptl/sysdeps/pthread/sigaction.c |3 +-- > 2 files changed, 16 insertions(+), 6 deletions(-) > > diff --git a/libc/sysdeps/linux/mips/sigaction.c > b/libc/sysdeps/linux/mips/sigaction.c > > index f2d2747..26b816c 100644 > --- a/libc/sysdeps/linux/mips/sigaction.c > +++ b/libc/sysdeps/linux/mips/sigaction.c > @@ -27,8 +27,9 @@ > > #define SA_RESTORER 0x0400 > > -extern __typeof(sigaction) __libc_sigaction; > > - > +#ifdef NOT_IN_libc > +extern __typeof(sigaction) __libc_sigaction; > +#endif > > #ifdef __NR_rt_sigaction > > @@ -43,7 +44,12 @@ static void restore(void) __asm__ ("__restore"); > > /* If ACT is not NULL, change the action for SIG to *ACT. > > If OACT is not NULL, put the old action for SIG in *OACT. */ > -int __libc_sigaction(int sig, const struct sigaction *act, struct > sigaction *oact) > +#ifdef NOT_IN_libc > +int > +#else > +static int > +#endif > > +__libc_sigaction(int sig, const struct sigaction *act, struct sigaction > *oact) > { > # if _MIPS_SIM != _ABIO32 > struct sigaction kact; > @@ -65,7 +71,12 @@ extern void restore(void) __asm__ ("__restore") > attribute_hidden; > > > /* If ACT is not NULL, change the action for SIG to *ACT. > If OACT is not NULL, put the old action for SIG in *OACT. */ > -int __libc_sigaction(int sig, const struct sigaction *act, struct > sigaction *oact) > > +#ifdef NOT_IN_libc > +in
Re: static linking failed with sigaction testing program
On Fri, Mar 25, 2011 at 6:33 PM, Peter Mazinger wrote: > I assume you are using NPTL as threads, NPTL devs, one of the __sigactions > needs probably be weak > I would say, do not use that syntax, the compiler defaults should be correct > (speak, -lc is added at the end of linking, if any earlier > __sigaction was seen in a library provided on command line by > -l, libc should provide a weak to not conflict > To really fix it, we have to get rid of all duplicated *sigactions, only one > should stay (preferably in libc IMHO) Since my glibc-based host PC has no problem compiling the test program regardless of the link order, I checked to see how glibc implements the symbol types: libc.a: sigaction.o: 0220 T __sigaction 0220 W sigaction libpthread.a: sigaction.o: 0220 T __sigaction 0220 W sigaction What is the general consensus on how closely uClibc should try to mirror glibc on these sorts of issues? Is it worth figuring out what they did differently? ___ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc
Re: static linking failed with sigaction testing program
On Sat, Mar 26, 2011 at 9:24 PM, Kevin Cernekee wrote: > On Fri, Mar 25, 2011 at 6:33 PM, Peter Mazinger wrote: >> To really fix it, we have to get rid of all duplicated *sigactions, only one >> should stay (preferably in libc IMHO) > > Since my glibc-based host PC has no problem compiling the test program > regardless of the link order, I checked to see how glibc implements > the symbol types: really you should be looking at how the linker processes things. use -Wl,-M for both. -mike ___ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc
Re: static linking failed with sigaction testing program
On Sat, Mar 26, 2011 at 10:26 PM, Mike Frysinger wrote: > really you should be looking at how the linker processes things. use > -Wl,-M for both. Thanks for the tip. That is useful. So, for "-static -lpthread -lc" on uClibc: The test program needs sigaction(), and this pulls in libpthread.a(pt-sigaction.os). So far so good. But later on, libc.a(abort.os) needs __GI_sigaction(). This symbol exists in libc.a(sigaction.os) but not in libpthread.a(pt-sigaction.os). So the linker winds up grabbing both .os files. A few strong symbols are duplicated in both libc.a(sigaction.os) and libpthread.a(pt-sigaction.os), which causes the link to fail. For "-static -lpthread -lc" on glibc, there is no __GI_sigaction() to complicate matters. abort() calls __sigaction(). Either libc.a(sigaction.o) or libpthread.a(sigaction.o) can satisfy this dependency, so there is no reason why the linker would ever try to grab both copies of sigaction.o . Interestingly, if I rebuild uClibc with DOPIC disabled, libpthread.a(pt-sigaction.o) now contains __GI_sigaction() and thus the conflict vanishes. I don't know why DOPIC was enabled in the first place, or what else might break due to the change. Time to run some more tests. ___ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc
Re: static linking failed with sigaction testing program
My preferance would be to remove the duplicates and implement only one of these functions in libc Peter Original-Nachricht > Datum: Sun, 27 Mar 2011 00:33:20 -0700 > Von: Kevin Cernekee > An: Mike Frysinger > CC: Peter Mazinger , Jian Peng , > uclibc@uclibc.org > Betreff: Re: static linking failed with sigaction testing program > On Sat, Mar 26, 2011 at 10:26 PM, Mike Frysinger > wrote: > > really you should be looking at how the linker processes things. use > > -Wl,-M for both. > > Thanks for the tip. That is useful. > > So, for "-static -lpthread -lc" on uClibc: > > The test program needs sigaction(), and this pulls in > libpthread.a(pt-sigaction.os). So far so good. > > But later on, libc.a(abort.os) needs __GI_sigaction(). This symbol > exists in libc.a(sigaction.os) but not in > libpthread.a(pt-sigaction.os). So the linker winds up grabbing both > .os files. A few strong symbols are duplicated in both > libc.a(sigaction.os) and libpthread.a(pt-sigaction.os), which causes > the link to fail. > > For "-static -lpthread -lc" on glibc, there is no __GI_sigaction() to > complicate matters. abort() calls __sigaction(). Either > libc.a(sigaction.o) or libpthread.a(sigaction.o) can satisfy this > dependency, so there is no reason why the linker would ever try to > grab both copies of sigaction.o . > > Interestingly, if I rebuild uClibc with DOPIC disabled, > libpthread.a(pt-sigaction.o) now contains __GI_sigaction() and thus > the conflict vanishes. > > I don't know why DOPIC was enabled in the first place, or what else > might break due to the change. Time to run some more tests. -- GMX DSL Doppel-Flat ab 19,99 Euro/mtl.! Jetzt mit gratis Handy-Flat! http://portal.gmx.net/de/go/dsl ___ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc