When building a file with -fPIE -pie and -Wl,--no-export-dynamic it still export dynamic symbols not exported for a "normal" executable. According to info ld this should normally not happen, but does not specify what is considered not normal. As this behavior actually breaks the testsuite for ld if you compile it with -fPIE -pie my question is if this is a bug that should be fixed or if this is considered expected. Example below on how to reporoduce (have reproduced on a Fedora 13-system running ld 2.20.51.0.2, and on a Gentoo box running 2.20.1), the vers4.c file can be found in the testsuite as ld/testsuite/ld-elfvers/vers4.c: $ cat vers4.c /* * Testcase to make sure that a versioned symbol definition in an * application correctly defines the version node, if and only if * the actual symbol is exported. This is built both with and without * -export-dynamic. */ #include <stdio.h> extern int foo (); int bar() { return 3; } int new_foo() { return 1000+bar(); } __asm__(".symver new_foo,foo@@VERS_2.0"); int main() { printf("%d\n", foo()); return 0; } $ gcc -o test1 -Wl,--no-export-dynamic vers4.c $ gcc -o test2 -fPIE -pie -Wl,--no-export-dynamic vers4.c $ objdump -T test* test1: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail test2: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000000270 l d .interp 0000000000000000 .interp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail 00000000000008be g DF .text 000000000000003c VERS_2.0 foo 0000000000201020 g D *ABS* 0000000000000000 Base _end 0000000000201010 g D *ABS* 0000000000000000 Base _edata 0000000000000960 g DF .text 0000000000000088 Base __libc_csu_init 0000000000201010 g D *ABS* 0000000000000000 Base __bss_start 0000000000000000 g DO *ABS* 0000000000000000 VERS_2.0 VERS_2.0 00000000000008fa g DF .text 0000000000000054 Base main 0000000000000950 g DF .text 0000000000000002 Base __libc_csu_fini
This patch works for me: diff --git a/bfd/elflink.c b/bfd/elflink.c index 8f6b5f4..98ea753 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -1715,7 +1715,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, { if (! dynamic) { - if (info->shared + if (! info->executable || hi->ref_dynamic) *dynsym = TRUE; } @@ -1784,7 +1784,7 @@ nondefault: { if (! dynamic) { - if (info->shared + if (! info->executable || hi->ref_dynamic) *dynsym = TRUE; }
Subject: Bug 11413 CVSROOT: /cvs/src Module name: src Changes by: hjl@sourceware.org 2010-03-21 23:26:33 Modified files: bfd : ChangeLog elflink.c Log message: Check !executable instead of shared for PIE. 2010-03-21 H.J. Lu <hongjiu.lu@intel.com> PR ld/11413 * elflink.c (_bfd_elf_add_default_symbol): Check !executable instead of shared. Patches: http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/ChangeLog.diff?cvsroot=src&r1=1.4961&r2=1.4962 http://sourceware.org/cgi-bin/cvsweb.cgi/src/bfd/elflink.c.diff?cvsroot=src&r1=1.370&r2=1.371
Fixed.
Thanks for that, now the testcase passes. But there is still more things exported when compiling a PIE file, then when compiling a "normal" file, is this something we have to live with? $ gcc -o test1 -Wl,--no-export-dynamic vers4.c $ gcc -o test2 -fPIE -pie -Wl,--no-export-dynamic vers4.c $ objdump -T test* test1: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail test2: file format elf64-x86-64 DYNAMIC SYMBOL TABLE: 0000000000000270 l d .interp 0000000000000000 .interp 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 printf 0000000000000000 w D *UND* 0000000000000000 __gmon_start__ 0000000000000000 w D *UND* 0000000000000000 _Jv_RegisterClasses 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.2.5 __libc_start_main 0000000000000000 w DF *UND* 0000000000000000 GLIBC_2.2.5 __cxa_finalize 0000000000000000 DF *UND* 0000000000000000 GLIBC_2.4 __stack_chk_fail 0000000000201020 g D *ABS* 0000000000000000 Base _end 0000000000201010 g D *ABS* 0000000000000000 Base _edata 00000000000008e0 g DF .text 0000000000000088 Base __libc_csu_init 0000000000201010 g D *ABS* 0000000000000000 Base __bss_start 000000000000087a g DF .text 0000000000000054 Base main 00000000000008d0 g DF .text 0000000000000002 Base __libc_csu_fini