[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Bug ld/5448] New: Weak functions support is broken.
From: |
alex at alemate dot ru |
Subject: |
[Bug ld/5448] New: Weak functions support is broken. |
Date: |
5 Dec 2007 00:27:45 -0000 |
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 ld/5448] New: Weak functions support is broken.,
alex at alemate dot ru <=