[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:

#pragma weak    foo

extern  void    foo(char *);

int main(){
        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

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

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


------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.

reply via email to

[Prev in Thread] Current Thread [Next in Thread]