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_i...@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",@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,"",@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
_______________________________________________
uClibc mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/uclibc