This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] PR ld/19636: pie changes program behavior and generate unnecessary dynamic symbols


On Mon, Feb 15, 2016 at 07:00:32AM -0800, H.J. Lu wrote:
> Non-dynamic symbols are always bound locally in PIE and we always create
> the dynsym section, even if it is empty, with dynamic sections.
> 
> I fixed x86.  Other backends need similar fix.  Any comments?
> 

Symbols are always bound locally to their definitions in PIE, similar to
-shared -Bsymbolic and we always create the dynsym section, even if it is
empty, with dynamic sections.

I fixed x86.  Other backends need similar fix.  Any comments?

H.J.
----
bfd/

	PR ld/19636
	* elf-bfd.h (SYMBOLIC_BIND): Bind symbols to their definitions
	locally in PIE.
	* elf32-i386.c (elf_i386_allocate_dynrelocs): Discard relocations
	against locally bound weak undefined symbols.
	(elf_i386_relocate_section): Don't generate dynamic relocations
	against locally bound weak undefined symbols.
	* elf64-x86-64.c (elf_x86_64_allocate_dynrelocs): Discard
	relocations on locally bound weak undefined symbols.
	(elf_x86_64_relocate_section): Don't generate dynamic relocations
	against locally bound weak undefined symbols.
	* elflink.c (bfd_elf_record_link_assignment): Make the linker
	assigned symbol dynamic for shared library or relocatable
	executable.
	(_bfd_elf_link_renumber_dynsyms): Check for shared library,
	instead of PIC.  Always create the dynsym section, even if it is
	empty, with dynamic sections.
	(bfd_elf_final_link): Check for shared library, instead of PIC,
	when writing out the section symbols.

ld/

	PR ld/19636
	* testsuite/ld-elf/pr19636.s: New file.
	* testsuite/ld-elf/pr19636a.d: Likewise.
	* testsuite/ld-elf/pr19636b.d: Likewise.
	* testsuite/ld-elf/pr19636c.d: Likewise.
	* testsuite/ld-x86-64/pr13082-3b.d: Updated.
	* testsuite/ld-x86-64/pr13082-4b.d: Likewise.
---
 bfd/elf-bfd.h                       | 13 ++++++++-----
 bfd/elf32-i386.c                    | 15 ++++++++++-----
 bfd/elf64-x86-64.c                  | 14 +++++++++-----
 bfd/elflink.c                       | 14 +++++++-------
 ld/testsuite/ld-elf/pr19636.s       |  5 +++++
 ld/testsuite/ld-elf/pr19636a.d      | 10 ++++++++++
 ld/testsuite/ld-elf/pr19636b.d      |  6 ++++++
 ld/testsuite/ld-elf/pr19636c.d      |  6 ++++++
 ld/testsuite/ld-x86-64/pr13082-3b.d |  4 +---
 ld/testsuite/ld-x86-64/pr13082-4b.d |  4 +---
 10 files changed, 63 insertions(+), 28 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/pr19636.s
 create mode 100644 ld/testsuite/ld-elf/pr19636a.d
 create mode 100644 ld/testsuite/ld-elf/pr19636b.d
 create mode 100644 ld/testsuite/ld-elf/pr19636c.d

diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h
index ea4d59a..3a2617b 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -2639,11 +2639,14 @@ extern asection _bfd_elf_large_com_section;
     continue;								\
   }
 
-/* Will a symbol be bound to the definition within the shared
-   library, if any.  A unique symbol can never be bound locally.  */
-#define SYMBOLIC_BIND(INFO, H) \
-    (!(H)->unique_global \
-     && ((INFO)->symbolic || ((INFO)->dynamic && !(H)->dynamic)))
+/* Will a symbol be bound to the definition within the PIC object, if
+   any.  A unique symbol can never be bound locally.  Symbols are always
+   bound locally in PIE, similar to -shared -Bsymbolic.  */
+#define SYMBOLIC_BIND(INFO, H)						\
+    (!(H)->unique_global						\
+     && ((INFO)->symbolic						\
+	 || ((INFO)->dynamic && !(H)->dynamic)				\
+	 || bfd_link_pie (INFO)))
 
 #ifdef __cplusplus
 }
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index a8951d8..f3414ba 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -2611,11 +2611,12 @@ elf_i386_allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
 	}
 
       /* Also discard relocs on undefined weak syms with non-default
-    	 visibility.  */
+	 visibility or bound locally.  */
       if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
 	{
-	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+	      || SYMBOLIC_BIND (info, h))
 	    eh->dyn_relocs = NULL;
 
 	  /* Make sure undefined weak symbols are output as a dynamic
@@ -4244,11 +4245,15 @@ r_386_got32:
 	      || is_vxworks_tls)
 	    break;
 
-	  /* Copy dynamic function pointer relocations.  */
+	  /* Copy dynamic function pointer relocations.  Don't generate
+	     dynamic relocations against locally bound weak undefined
+	     symbols.  */
 	  if ((bfd_link_pic (info)
 	       && (h == NULL
-		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		   || h->root.type != bfd_link_hash_undefweak)
+		   || (!(h->root.type == bfd_link_hash_undefweak
+			 && SYMBOLIC_BIND (info, h))
+		       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+			   || h->root.type != bfd_link_hash_undefweak)))
 	       && ((r_type != R_386_PC32 && r_type != R_386_SIZE32)
 		   || !SYMBOL_CALLS_LOCAL (info, h)))
 	      || (ELIMINATE_COPY_RELOCS
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index 463ce3a..5e96e00 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -2832,12 +2832,13 @@ elf_x86_64_allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf)
 	}
 
       /* Also discard relocs on undefined weak syms with non-default
-	 visibility.  */
+	 visibility or bound locally.  */
       if (eh->dyn_relocs != NULL)
 	{
 	  if (h->root.type == bfd_link_hash_undefweak)
 	    {
-	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+		  || SYMBOLIC_BIND (info, h))
 		eh->dyn_relocs = NULL;
 
 	      /* Make sure undefined weak symbols are output as a dynamic
@@ -4585,7 +4586,8 @@ direct:
 	   /* Don't copy a pc-relative relocation into the output file
 	      if the symbol needs copy reloc or the symbol is undefined
 	      when building executable.  Copy dynamic function pointer
-	      relocations.  */
+	      relocations.  Don't generate dynamic relocations against
+	      locally bound weak undefined symbols.  */
 	  if ((bfd_link_pic (info)
 	       && !(bfd_link_executable (info)
 		    && h != NULL
@@ -4594,8 +4596,10 @@ direct:
 			|| h->root.type == bfd_link_hash_undefined)
 		    && IS_X86_64_PCREL_TYPE (r_type))
 	       && (h == NULL
-		   || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-		   || h->root.type != bfd_link_hash_undefweak)
+		   || (!(h->root.type == bfd_link_hash_undefweak
+			 && SYMBOLIC_BIND (info, h))
+		       && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+			   || h->root.type != bfd_link_hash_undefweak)))
 	       && ((! IS_X86_64_PCREL_TYPE (r_type)
 		      && r_type != R_X86_64_SIZE32
 		      && r_type != R_X86_64_SIZE64)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ac03ce5..c3fa20d 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -632,8 +632,8 @@ bfd_elf_record_link_assignment (bfd *output_bfd,
 
   if ((h->def_dynamic
        || h->ref_dynamic
-       || bfd_link_pic (info)
-       || (bfd_link_pde (info)
+       || bfd_link_dll (info)
+       || (bfd_link_executable (info)
 	   && elf_hash_table (info)->is_relocatable_executable))
       && h->dynindx == -1)
     {
@@ -844,7 +844,7 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
 {
   unsigned long dynsymcount = 0;
 
-  if (bfd_link_pic (info)
+  if (bfd_link_dll (info)
       || elf_hash_table (info)->is_relocatable_executable)
     {
       const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
@@ -875,9 +875,9 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd,
 			  &dynsymcount);
 
   /* There is an unused NULL entry at the head of the table which
-     we must account for in our count.  Unless there weren't any
-     symbols, which means we'll have no table at all.  */
-  if (dynsymcount != 0)
+     we must account for in our count.  We always create the dynsym
+     section, even if it is empty, with dynamic sections.  */
+  if (elf_hash_table (info)->dynamic_sections_created)
     ++dynsymcount;
 
   elf_hash_table (info)->dynsymcount = dynsymcount;
@@ -11484,7 +11484,7 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
       long last_local = 0;
 
       /* Write out the section symbols for the output sections.  */
-      if (bfd_link_pic (info)
+      if (bfd_link_dll (info)
 	  || elf_hash_table (info)->is_relocatable_executable)
 	{
 	  asection *s;
diff --git a/ld/testsuite/ld-elf/pr19636.s b/ld/testsuite/ld-elf/pr19636.s
new file mode 100644
index 0000000..9bd7e4a
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19636.s
@@ -0,0 +1,5 @@
+	.text
+	.weak func
+	.globl _start
+_start:
+	.dc.a func
diff --git a/ld/testsuite/ld-elf/pr19636a.d b/ld/testsuite/ld-elf/pr19636a.d
new file mode 100644
index 0000000..f645d09
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19636a.d
@@ -0,0 +1,10 @@
+#source: pr19636.s
+#ld: -pie
+#readelf : -r --dyn-syms --wide
+#target: x86_64-*-linux* i?86-*-linux-gnu
+
+There are no relocations in this file.
+
+Symbol table '\.dynsym' contains 1 entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+ +0: 0+ +0 +NOTYPE +LOCAL +DEFAULT +UND +
diff --git a/ld/testsuite/ld-elf/pr19636b.d b/ld/testsuite/ld-elf/pr19636b.d
new file mode 100644
index 0000000..c461a09
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19636b.d
@@ -0,0 +1,6 @@
+#source: pr19636.s
+#ld: -pie -E
+#readelf : -r --wide
+#target: x86_64-* i?86-*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-elf/pr19636c.d b/ld/testsuite/ld-elf/pr19636c.d
new file mode 100644
index 0000000..6cf7d0e
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr19636c.d
@@ -0,0 +1,6 @@
+#source: pr19636.s
+#ld: -shared -Bsymbolic
+#readelf : -r --wide
+#target: x86_64-* i?86-*
+
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr13082-3b.d b/ld/testsuite/ld-x86-64/pr13082-3b.d
index 12efaf0..766dd74 100644
--- a/ld/testsuite/ld-x86-64/pr13082-3b.d
+++ b/ld/testsuite/ld-x86-64/pr13082-3b.d
@@ -4,6 +4,4 @@
 #ld: -pie -melf32_x86_64
 #readelf: -r --wide
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_32 +[0-9a-f]+ +func \+ 0
+There are no relocations in this file.
diff --git a/ld/testsuite/ld-x86-64/pr13082-4b.d b/ld/testsuite/ld-x86-64/pr13082-4b.d
index cb4d90a..6d4a35b 100644
--- a/ld/testsuite/ld-x86-64/pr13082-4b.d
+++ b/ld/testsuite/ld-x86-64/pr13082-4b.d
@@ -4,6 +4,4 @@
 #ld: -pie -melf32_x86_64
 #readelf: -r --wide
 
-Relocation section '.rela.dyn' at offset 0x[0-9a-f]+ contains 1 entries:
- Offset     Info    Type                Sym. Value  Symbol's Name \+ Addend
-[0-9a-f]+ +[0-9a-f]+ +R_X86_64_64 +[0-9a-f]+ +func \+ 1
+There are no relocations in this file.
-- 
2.5.0


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]