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

Attachment: 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

Reply via email to