* PowerPC64 PLT vs. mixed objects
@ 2005-02-11 11:16 Alan Modra
2005-02-11 15:59 ` Alan Modra
0 siblings, 1 reply; 2+ messages in thread
From: Alan Modra @ 2005-02-11 11:16 UTC (permalink / raw)
To: binutils
We were generating duplicate PLT entries when the linker was fed a mix
of dot-sym and no-dot-sym objects. Fixed as follows.
* elf64-ppc.c (move_plt_plist): New function, extracted from..
(ppc64_elf_copy_indirect_symbol): ..here.
(func_desc_adjust): Use move_plt_plist.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.189
diff -u -p -r1.189 elf64-ppc.c
--- bfd/elf64-ppc.c 6 Feb 2005 10:29:39 -0000 1.189
+++ bfd/elf64-ppc.c 11 Feb 2005 03:32:22 -0000
@@ -3766,6 +3766,41 @@ ppc64_elf_create_dynamic_sections (bfd *
return TRUE;
}
+/* Move PLT info on FROM and merge with that on TO. */
+
+static void
+move_plt_plist (struct ppc_link_hash_entry *from,
+ struct ppc_link_hash_entry *to)
+{
+ if (from->elf.plt.plist != NULL)
+ {
+ if (to->elf.plt.plist != NULL)
+ {
+ struct plt_entry **entp;
+ struct plt_entry *ent;
+
+ for (entp = &from->elf.plt.plist; (ent = *entp) != NULL; )
+ {
+ struct plt_entry *dent;
+
+ for (dent = to->elf.plt.plist; dent != NULL; dent = dent->next)
+ if (dent->addend == ent->addend)
+ {
+ dent->plt.refcount += ent->plt.refcount;
+ *entp = ent->next;
+ break;
+ }
+ if (dent == NULL)
+ entp = &ent->next;
+ }
+ *entp = to->elf.plt.plist;
+ }
+
+ to->elf.plt.plist = from->elf.plt.plist;
+ from->elf.plt.plist = NULL;
+ }
+}
+
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
@@ -3868,33 +3903,7 @@ ppc64_elf_copy_indirect_symbol
}
/* And plt entries. */
- if (eind->elf.plt.plist != NULL)
- {
- if (edir->elf.plt.plist != NULL)
- {
- struct plt_entry **entp;
- struct plt_entry *ent;
-
- for (entp = &eind->elf.plt.plist; (ent = *entp) != NULL; )
- {
- struct plt_entry *dent;
-
- for (dent = edir->elf.plt.plist; dent != NULL; dent = dent->next)
- if (dent->addend == ent->addend)
- {
- dent->plt.refcount += ent->plt.refcount;
- *entp = ent->next;
- break;
- }
- if (dent == NULL)
- entp = &ent->next;
- }
- *entp = edir->elf.plt.plist;
- }
-
- edir->elf.plt.plist = eind->elf.plt.plist;
- eind->elf.plt.plist = NULL;
- }
+ move_plt_plist (eind, edir);
if (edir->elf.dynindx == -1)
{
@@ -5462,11 +5471,7 @@ func_desc_adjust (struct elf_link_hash_e
fdh->elf.non_got_ref |= fh->elf.non_got_ref;
if (ELF_ST_VISIBILITY (fh->elf.other) == STV_DEFAULT)
{
- struct plt_entry **ep = &fdh->elf.plt.plist;
- while (*ep != NULL)
- ep = &(*ep)->next;
- *ep = fh->elf.plt.plist;
- fh->elf.plt.plist = NULL;
+ move_plt_plist (fh, fdh);
fdh->elf.needs_plt = 1;
}
fdh->is_func_descriptor = 1;
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: PowerPC64 PLT vs. mixed objects
2005-02-11 11:16 PowerPC64 PLT vs. mixed objects Alan Modra
@ 2005-02-11 15:59 ` Alan Modra
0 siblings, 0 replies; 2+ messages in thread
From: Alan Modra @ 2005-02-11 15:59 UTC (permalink / raw)
To: binutils
On Fri, Feb 11, 2005 at 02:16:28PM +1030, Alan Modra wrote:
> We were generating duplicate PLT entries when the linker was fed a mix
> of dot-sym and no-dot-sym objects.
Sigh. Yet another problem with mixtures of dot-sym and no-dot-sym
object files. This time it was a bad decision regarding the need for
toc adjusting stubs on calls into a section of an old-style object.
The old-style object in question made plt calls, so needed r2 to be
correct, but the code checking for plt calls ignored all undefined
syms. With an old-style object making calls to a new-style dynamic lib,
the symbol on the branch reloc will stay undefined. A bad r2 value
results in a wild call which usually segfaults.
* elf64-ppc.c (toc_adjusting_stub_needed): Return true for
old-style branches to undefined dot-symbols which will be
satisfied by a plt call.
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.190
diff -u -p -r1.190 elf64-ppc.c
--- bfd/elf64-ppc.c 11 Feb 2005 03:47:40 -0000 1.190
+++ bfd/elf64-ppc.c 11 Feb 2005 14:10:16 -0000
@@ -8361,13 +8361,27 @@ toc_adjusting_stub_needed (struct bfd_li
break;
}
- /* Ignore branches to undefined syms. */
+ /* Calls to dynamic lib functions go through a plt call stub
+ that uses r2. Branches to undefined symbols might be a call
+ using old-style dot symbols that can be satisfied by a plt
+ call into a new-style dynamic library. */
if (sym_sec == NULL)
- continue;
+ {
+ struct ppc_link_hash_entry *eh = (struct ppc_link_hash_entry *) h;
+ if (eh != NULL
+ && eh->oh != NULL
+ && eh->oh->elf.plt.plist != NULL)
+ {
+ ret = 1;
+ break;
+ }
- /* Calls to dynamic lib functions go through a plt call stub
- that uses r2. Assume branches to other sections not included
- in the link need stubs too, to cover -R and absolute syms. */
+ /* Ignore other undefined symbols. */
+ continue;
+ }
+
+ /* Assume branches to other sections not included in the link need
+ stubs too, to cover -R and absolute syms. */
if (sym_sec->output_section == NULL)
{
ret = 1;
@@ -8389,7 +8403,6 @@ toc_adjusting_stub_needed (struct bfd_li
opd_adjust = get_opd_info (sym_sec);
if (opd_adjust != NULL)
{
-
if (h == NULL)
{
long adjust;
--
Alan Modra
IBM OzLabs - Linux Technology Centre
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2005-02-11 14:18 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-02-11 11:16 PowerPC64 PLT vs. mixed objects Alan Modra
2005-02-11 15:59 ` Alan Modra
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).