This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
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