[PATCH] fix static link
matthieu castet
castet.matthieu at free.fr
Tue Dec 29 23:44:14 UTC 2009
Denys Vlasenko a écrit :
> On Monday 28 December 2009 18:37, matthieu castet wrote:
>> Hi,
>>
>> gcc with the -fpic option optimize code like :
>> __attribute__ ((visibility ("hidden")))
>> # define weak_function __attribute__ ((weak))
>>
>> extern void weak_function _stdio_init(void) attribute_hidden;
>>
>>
>> int main()
>> {
>> if (_stdio_init)
>> _stdio_init();
>>
>> return 0;
>> }
>>
>>
>> to
>>
>> __attribute__ ((visibility ("hidden")))
>> # define weak_function __attribute__ ((weak))
>>
>> extern void weak_function _stdio_init(void) attribute_hidden;
>>
>>
>> int main()
>> {
>> _stdio_init();
>>
>> return 0;
>> }
>>
>> This crash if _stdio_init is null (because the linker didn't put it)
>> Without this patch, it is impossible to static link default config uClibc on x86.
> The problem is, C/C++ says that function's address is never NULL,
> and gcc uses this.
No weak function are special. The problem seems to be a gcc bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32219 .
But I wonder if it will be corrected one day.
>
> How about using asm() to prevent gcc from understanding that the pointer
> is a function pointer?
>
$cat p.c
#define attribute_hidden __attribute__ ((visibility ("hidden")))
# define weak_function __attribute__ ((weak))
extern void weak_function _stdio_init(void) attribute_hidden;
static inline __attribute__ ((__always_inline__)) int not_null(const void *p)
{
const void *q;
asm (""
: "=r" (q) /* output */
: "0" (p) /* input */
);
return q != 0;
}
int main()
{
if (not_null(_stdio_init))
_stdio_init();
return 0;
}
$gcc -fpic -O3 p.c -S
$cat p.s
.file "p.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
pushl %ebp
movl %esp, %ebp
subl $8, %esp
movl %ebx, 4(%esp)
call __i686.get_pc_thunk.bx
addl $_GLOBAL_OFFSET_TABLE_, %ebx
movl %ecx, (%esp)
leal _stdio_init at GOTOFF(%ebx), %eax
testl %eax, %eax
je .L2
call _stdio_init
.L2:
movl (%esp), %ecx
xorl %eax, %eax
movl 4(%esp), %ebx
movl %ebp, %esp
popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
.weak _stdio_init
.hidden _stdio_init
.ident "GCC: (Debian 4.3.4-6) 4.3.4"
.section .text.__i686.get_pc_thunk.bx,"axG", at progbits,__i686.get_pc_thunk.bx,comdat
.globl __i686.get_pc_thunk.bx
.hidden __i686.get_pc_thunk.bx
.type __i686.get_pc_thunk.bx, @function
__i686.get_pc_thunk.bx:
movl (%esp), %ebx
ret
.section .note.GNU-stack,"", at progbits
Notice the usage of a GOT even if the symbol is hidden...
>
> Care to remake the patch to use such not_null() wrapper?
> Please also add a comment above it with explanation
> why it is needed.
Ok
Matthieu
More information about the uClibc
mailing list