[PATCH] Static linking binaries with uClibc
Denys Vlasenko
vda.linux at googlemail.com
Sun May 16 04:59:12 UTC 2010
On Wednesday 03 February 2010 17:21, Will Newton wrote:
> 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
Ew can use asm() to prevent gcc from understanding that the pointer
is a function pointer.
Test program:
extern void g1(void);
extern void g2(void);
static inline __attribute__ ((__always_inline__)) int not_null(const void *p)
{
const void *q;
asm (""
: "=r" (q) /* output */
: "0" (p) /* input */
);
return q != 0;
}
void f1()
{
if (g1) g1();
}
void f2()
{
if (not_null(g2)) g2();
}
Resulting code with gcc -Os -fomit-frame-pointer -S t.c:
f2:
movl $g2, %eax
testl %eax, %eax
je .L4
jmp g2
.L4:
ret
f1:
jmp g1
--
vda
More information about the uClibc
mailing list