Weak symbols resolution is always done at compile time. If symbol is not known at compile time, its address is silently assumed 0. Example:
bar.c: #pragma weak foo extern void foo(char *); int main(){ foo("Test.\n"); return 0; } $gcc -o bar bar.c $objdump -x bar | grep foo 00000000 w *UND* 00000000 foo $objdump -R bar bar: file format elf32-i386 DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 080494e8 R_386_GLOB_DAT __gmon_start__ 080494f8 R_386_JUMP_SLOT __gmon_start__ 080494fc R_386_JUMP_SLOT __libc_start_main $objdump -D bar ...08048314 <main>: 8048314: 8d 4c 24 04 lea 0x4(%esp),%ecx 8048318: 83 e4 f0 and $0xfffffff0,%esp 804831b: ff 71 fc pushl 0xfffffffc(%ecx) 804831e: 55 push %ebp 804831f: 89 e5 mov %esp,%ebp 8048321: 51 push %ecx 8048322: 83 ec 04 sub $0x4,%esp 8048325: c7 04 24 00 84 04 08 movl $0x8048400,(%esp) 804832c: e8 cf 7c fb f7 call 0 <_init-0x8048230> 8048331: b8 00 00 00 00 mov $0x0,%eax 8048336: 83 c4 04 add $0x4,%esp 8048339: 59 pop %ecx 804833a: 5d pop %ebp 804833b: 8d 61 fc lea 0xfffffffc(%ecx),%esp 804833e: c3 ret 804833f: 90 nop ... So, as there is no entry for foo in dynamic relocation table, call is always done at static address 0. But the SUN Solaris 9 linker produces: $objdump -R bar.sparc bar.sparc: file format elf32-big DYNAMIC RELOCATION RECORDS OFFSET TYPE VALUE 000106c8 UNKNOWN foo 000106cc UNKNOWN foo 000106d4 UNKNOWN foo 000106d8 UNKNOWN foo 00020810 UNKNOWN _Jv_RegisterClasses 00020818 UNKNOWN __deregister_frame_info 00020814 UNKNOWN __register_frame_info 000209a8 UNKNOWN _environ 0002084c UNKNOWN atexit 00020858 UNKNOWN exit 00020864 UNKNOWN _exit 00020870 UNKNOWN __deregister_frame_info 0002087c UNKNOWN __register_frame_info 00020888 UNKNOWN _Jv_RegisterClasses 00020894 UNKNOWN printf So, on Linux system preloading (via LD_PRELOAD) library with defined symbol doesn't work, but on Solaris (using SUN ld) everything works. Even this program works as expected: ----------------------------- #pragma weak foo extern void foo(char *); void bar(char * path) { void (* fptr)(char *); if ((fptr = foo) != 0) (* fptr)(path); } ----------------------------- But GNU ld always loads 0 to fptr... -- Summary: Weak functions support is broken. Product: binutils Version: 2.17 Status: NEW Severity: normal Priority: P2 Component: ld AssignedTo: unassigned at sources dot redhat dot com ReportedBy: alex at alemate dot ru CC: bug-binutils at gnu dot org http://sourceware.org/bugzilla/show_bug.cgi?id=5448 ------- You are receiving this mail because: ------- You are on the CC list for the bug, or are watching someone who is. _______________________________________________ bug-binutils mailing list bug-binutils@gnu.org http://lists.gnu.org/mailman/listinfo/bug-binutils