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: ld/2218: Weak undefined symbol doesn't work properly with PIE


On Sun, Feb 19, 2006 at 04:40:41PM -0800, H. J. Lu wrote:
> On Mon, Feb 20, 2006 at 10:19:39AM +1030, Alan Modra wrote:
> > 
> > After giving this some more thought, I'm inclined to say that this patch
> > does not belong in the generic ELF support.  The reason is that the
> > behaviour of weak undefined symbols is not well defined.  At least, I'm
> > not aware of any standard that says an undefined weak sym should be made
> > dynamic when dynamic objects are involved in the link.  I think it would
> > be quite reasonable for an ELF target to choose to resolve undefined
> > weak syms in an executable to zero at link time.
> > 
> > So I think we ought to patch each backend individually, painful as that
> > might be.  Note that many backends already handle undef weak syms
> > specially, eg. calling bfd_elf_link_record_dynamic_symbol for plt and
> > got references (even in non-pie exes).
> 
> I have no strong opionions on either approach as long as we can get
> undefined weak symbol in PIE to work correctly. If we want to make it
> target dependent, I'd like to add 2 hooks to ELF backend:
> 
> 1. fixup_undefined_weak_symbol, which will be called to fix up
> the undefined weak symbol. The default will be NULL.
> 2. pie_fixup_output_extsym, which be called to fix up output symbol
> for PIE. The default will also be NULL.
> 
> 2 generic versions will be provided and x86/x86-64/ia64 will use them.

I don't see that these are needed.  I'm testing the following.

	PR ld/2218
	* elf32-arm.c (allocate_dynrelocs): Ensure undef weak sym in pie
	is dynamic.
	* elf32-hppa.c (allocate_dynrelocs): Likewise.
	* elf32-i386.c (allocate_dynrelocs): Likewise.
	* elf32-s390.c (allocate_dynrelocs): Likewise.
	* elf32-sh.c (allocate_dynrelocs): Likewise.
	* elf64-s390.c (allocate_dynrelocs): Likewise.
	* elf64-x86-64.c (allocate_dynrelocs): Likewise.
	* elf32-m32r.c (allocate_dynrelocs): Likewise.  Discard relocs
	on undef weak with non-default visibility too.
	* elfxx-sparc.c (allocate_dynrelocs): Ditto.

Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.63
diff -u -p -r1.63 elf32-arm.c
--- bfd/elf32-arm.c	27 Jan 2006 14:11:43 -0000	1.63
+++ bfd/elf32-arm.c	20 Feb 2006 00:45:28 -0000
@@ -6333,9 +6333,22 @@ allocate_dynrelocs (struct elf_link_hash
 
       /* Also discard relocs on undefined weak syms with non-default
          visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->relocs_copied != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->relocs_copied = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->relocs_copied = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
+
       else if (htab->root.is_relocatable_executable && h->dynindx == -1
 	       && h->root.type == bfd_link_hash_new)
 	{
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.141
diff -u -p -r1.141 elf32-hppa.c
--- bfd/elf32-hppa.c	27 Dec 2005 22:50:08 -0000	1.141
+++ bfd/elf32-hppa.c	20 Feb 2006 00:45:30 -0000
@@ -2020,9 +2020,21 @@ allocate_dynrelocs (struct elf_link_hash
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT
+      if (hh->dyn_relocs != NULL
 	  && eh->root.type == bfd_link_hash_undefweak)
-	hh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT)
+	    hh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (eh->dynindx == -1
+		   && !eh->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, eh))
+		return FALSE;
+	    }
+	}
     }
   else
     {
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.151
diff -u -p -r1.151 elf32-i386.c
--- bfd/elf32-i386.c	18 Jan 2006 21:07:48 -0000	1.151
+++ bfd/elf32-i386.c	20 Feb 2006 00:45:33 -0000
@@ -1779,9 +1779,21 @@ allocate_dynrelocs (struct elf_link_hash
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.76
diff -u -p -r1.76 elf32-m32r.c
--- bfd/elf32-m32r.c	1 Dec 2005 04:48:13 -0000	1.76
+++ bfd/elf32-m32r.c	20 Feb 2006 00:45:35 -0000
@@ -2101,6 +2101,24 @@ allocate_dynrelocs (struct elf_link_hash
                 pp = &p->next;
             }
         }
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (eh->dyn_relocs != NULL
+	  && h->root.type == bfd_link_hash_undefweak)
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else
     {
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.79
diff -u -p -r1.79 elf32-s390.c
--- bfd/elf32-s390.c	25 Oct 2005 16:19:06 -0000	1.79
+++ bfd/elf32-s390.c	20 Feb 2006 00:45:36 -0000
@@ -1908,9 +1908,21 @@ allocate_dynrelocs (h, inf)
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.132
diff -u -p -r1.132 elf32-sh.c
--- bfd/elf32-sh.c	31 Dec 2005 16:23:13 -0000	1.132
+++ bfd/elf32-sh.c	20 Feb 2006 00:45:40 -0000
@@ -4160,9 +4160,21 @@ allocate_dynrelocs (struct elf_link_hash
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else
     {
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.79
diff -u -p -r1.79 elf64-s390.c
--- bfd/elf64-s390.c	25 Oct 2005 16:19:07 -0000	1.79
+++ bfd/elf64-s390.c	20 Feb 2006 00:45:41 -0000
@@ -1881,9 +1881,21 @@ allocate_dynrelocs (h, inf)
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.109
diff -u -p -r1.109 elf64-x86-64.c
--- bfd/elf64-x86-64.c	18 Jan 2006 21:07:48 -0000	1.109
+++ bfd/elf64-x86-64.c	20 Feb 2006 00:45:43 -0000
@@ -1565,9 +1565,21 @@ allocate_dynrelocs (struct elf_link_hash
 
       /* Also discard relocs on undefined weak syms with non-default
 	 visibility.  */
-      if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+      if (eh->dyn_relocs != NULL
 	  && h->root.type == bfd_link_hash_undefweak)
-	eh->dyn_relocs = NULL;
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else if (ELIMINATE_COPY_RELOCS)
     {
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.17
diff -u -p -r1.17 elfxx-sparc.c
--- bfd/elfxx-sparc.c	1 Feb 2006 22:03:38 -0000	1.17
+++ bfd/elfxx-sparc.c	20 Feb 2006 00:45:46 -0000
@@ -1935,6 +1935,24 @@ allocate_dynrelocs (struct elf_link_hash
 		pp = &p->next;
 	    }
 	}
+
+      /* Also discard relocs on undefined weak syms with non-default
+	 visibility.  */
+      if (eh->dyn_relocs != NULL
+	  && h->root.type == bfd_link_hash_undefweak)
+	{
+	  if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
+	    eh->dyn_relocs = NULL;
+
+	  /* Make sure undefined weak symbols are output as a dynamic
+	     symbol in PIEs.  */
+	  else if (h->dynindx == -1
+		   && !h->forced_local)
+	    {
+	      if (! bfd_elf_link_record_dynamic_symbol (info, h))
+		return FALSE;
+	    }
+	}
     }
   else
     {

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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