Bug 11413 - --no-export-dynamic broken for PIE?
Summary: --no-export-dynamic broken for PIE?
Status: RESOLVED FIXED
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: unspecified
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-21 13:13 UTC by Peter Hjalmarsson
Modified: 2010-03-22 08:23 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Hjalmarsson 2010-03-21 13:13:58 UTC
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
Comment 1 H.J. Lu 2010-03-21 19:26:22 UTC
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;
                }
Comment 2 Sourceware Commits 2010-03-21 23:27:05 UTC
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

Comment 3 H.J. Lu 2010-03-21 23:28:29 UTC
Fixed.
Comment 4 Peter Hjalmarsson 2010-03-22 08:23:42 UTC
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