Hello, I have a problem with linking applications statically with uClibc but without including the stdio functions. This issue has been brought up before, but it still does not seem to be solved.
The issue would appear to be this:
_stdio_init is declared as weak and hidden in
libc/misc/internals__uClibc_main.c:
extern void weak_function _stdio_init(void) attribute_hidden;
The reason it is defined hidden is to reduce the size of the external
symbol set of uClibc and to bypass the PLT when calling it, which is
really only of benefit in the shared library case. The reason it is
declared weak is so that when uClibc is linked statically, _stdio_init
is not called unless it has already pulled in by some other symbol.
However, static linking does not work in the no-stdio case at present.
Looking at the code and disassembly we see why - the compiler omits
the test for the null value of _stdio_init, e.g.:
/*
* Initialize stdio here. In the static library case, this will
* be bypassed if not needed because of the weak alias above.
* Thus we get a nice size savings because the stdio functions
* won't be pulled into the final static binary unless used.
*/
if (likely(_stdio_init != NULL))
_stdio_init();
}
34: e8 fc ff ff ff call 35 <__GI___uClibc_init+0x35>
39: 58 pop %eax
3a: 5a pop %edx
3b: 5b pop %ebx
3c: e9 fc ff ff ff jmp 3d <__GI___uClibc_init+0x3d>
41: 59 pop %ecx
42: 58 pop %eax
43: 5b pop %ebx
44: c3 ret
Note how a jmp is used instead of a call. gcc does this because it
believes that because _stdio_init is hidden, it must be defined within
the current component (shared library). This assumption is ok in a
shared library but when it comes to linking statically it is a problem
becase _stdio_init may not be defined.
My proposed fix is to remove the weak declaration of _stdio_init. This
has no downside for the shared library build. For the static library
build, although it does mean that _stdio_init is always included, the
support for not including _stdio_init seems to have been broken for
some time.
>From 97b0517b72d0892b7755019f8a96e6c367927c3a Mon Sep 17 00:00:00 2001
From: Will Newton <[email protected]>
Date: Wed, 3 Feb 2010 16:18:40 +0000
Subject: [PATCH] __uClibc_main: Make declaration of _stdio_init non-weak.
This fixes applications linking against uClibc statically but without
using stdio functions. Previously these applications would have no
definition of _stdio_init but the compiler would elide the test for
a NULL value and emit a jump with no offset instead.
Signed-off-by: Will Newton <[email protected]>
---
libc/misc/internals/__uClibc_main.c | 11 ++---------
1 files changed, 2 insertions(+), 9 deletions(-)
diff --git a/libc/misc/internals/__uClibc_main.c
b/libc/misc/internals/__uClibc_main.c
index 19acbe0..b3fcaf4 100644
--- a/libc/misc/internals/__uClibc_main.c
+++ b/libc/misc/internals/__uClibc_main.c
@@ -68,7 +68,7 @@ libc_hidden_proto(__errno_location)
extern int *weak_const_function __h_errno_location(void);
libc_hidden_proto(__h_errno_location)
-extern void weak_function _stdio_init(void) attribute_hidden;
+extern void _stdio_init(void) attribute_hidden;
#ifdef __UCLIBC_HAS_LOCALE__
extern void weak_function _locale_init(void) attribute_hidden;
#endif
@@ -211,14 +211,7 @@ void __uClibc_init(void)
_locale_init();
#endif
- /*
- * Initialize stdio here. In the static library case, this will
- * be bypassed if not needed because of the weak alias above.
- * Thus we get a nice size savings because the stdio functions
- * won't be pulled into the final static binary unless used.
- */
- if (likely(_stdio_init != NULL))
- _stdio_init();
+ _stdio_init();
}
libc_hidden_def(__uClibc_init)
--
1.5.5.2
0001-__uClibc_main-Make-declaration-of-_stdio_init-non-w.patch
Description: Binary data
_______________________________________________ uClibc mailing list [email protected] http://lists.busybox.net/mailman/listinfo/uclibc
