This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix PR1540, abort on reference to versioned symbol
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Wed, 26 Oct 2005 01:45:14 +0930
- Subject: Fix PR1540, abort on reference to versioned symbol
The linker currently aborts if one object file references an explicit
symbol version, and another file the default symbol version, when the
explicit version happens to be the same as the default provided by a
shared lib. (If that's confusing, see the testcase in the PR.) After
processing the two object files, we have
foo, with dyn link info
foo@VER_1, also with dyn link info
After processing the shared lib, we want to end up with
foo --------------> foo@@VER_1
^
foo@VER_1 -----------|
ie. both foo and foo@VER_1 become indirect references to the default
sym, foo@@VER_1, and we want the dynamic link info transferred to
foo@@VER_1. The trouble is that no matter which order we do the
transfer, at some point we require copy_indirect_symbol to handle a
direct and an indirect symbol both having dynamic link info.
_bfd_elf_link_hash_copy_indirect has never handled this situation,
neither have the various backend functions. The following should fix
this, but I'm a little unsure whether tacking ia64's dyn_sym_info lists
together is correct. Perhaps they ought to be merged in some manner.
Would an ia64 maintainer please look at this?
PR ld/1540
* elf-bfd.h (elf_backend_copy_indirect_symbol): Replace pointer to
elf_backend_data with pointer to bfd_link_info.
(_bfd_elf_link_hash_copy_indirect): Likewise.
* elf.c (_bfd_elf_link_hash_copy_indirect): Likewise. Handle
direct and indirect symbols both having dynamic link info.
* elf32-arm.c (elf32_arm_copy_indirect_symbol): Likewise.
* elf32-hppa.c (elf32_hppa_copy_indirect_symbol): Likewise.
* elf32-i386.c (elf_i386_copy_indirect_symbol): Likewise.
* elf32-m32r.c (m32r_elf_copy_indirect_symbol): Likewise.
* elf32-ppc.c (ppc_elf_copy_indirect_symbol): Likewise.
* elf32-s390.c (elf_s390_copy_indirect_symbol): Likewise.
* elf32-sh.c (sh_elf_copy_indirect_symbol): Likewise.
* elf64-ppc.c (ppc64_elf_copy_indirect_symbol): Likewise.
* elf64-s390.c (elf_s390_copy_indirect_symbol): Likewise.
* elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Likewise.
* elfxx-ia64.c (elfNN_ia64_hash_copy_indirect): Likewise.
* elfxx-mips.c (_bfd_mips_elf_copy_indirect_symbol): Likewise.
* elfxx-sparc.c (_bfd_sparc_elf_copy_indirect_symbol): Likewise.
* elflink.c: Adjust all calls to bed->elf_backend_copy_indirect_symbol.
* elfxx-mips.h (_bfd_mips_elf_copy_indirect_symbol): Update prototype.
* elfxx-sparc.h (_bfd_sparc_elf_copy_indirect_symbol): Likewise.
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.198
diff -u -p -r1.198 elf-bfd.h
--- bfd/elf-bfd.h 24 Oct 2005 01:40:58 -0000 1.198
+++ bfd/elf-bfd.h 25 Oct 2005 12:59:12 -0000
@@ -870,7 +870,7 @@ struct elf_backend_data
newly created and plt/got refcounts and dynamic indices should not
be copied. */
void (*elf_backend_copy_indirect_symbol)
- (const struct elf_backend_data *, struct elf_link_hash_entry *,
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
/* Modify any information related to dynamic linking such that the
@@ -1462,7 +1462,7 @@ extern struct bfd_hash_entry *_bfd_elf_l
extern struct bfd_link_hash_table *_bfd_elf_link_hash_table_create
(bfd *);
extern void _bfd_elf_link_hash_copy_indirect
- (const struct elf_backend_data *, struct elf_link_hash_entry *,
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern void _bfd_elf_link_hash_hide_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.316
diff -u -p -r1.316 elf.c
--- bfd/elf.c 24 Oct 2005 01:40:58 -0000 1.316
+++ bfd/elf.c 25 Oct 2005 12:59:17 -0000
@@ -1458,12 +1458,11 @@ _bfd_elf_link_hash_newfunc (struct bfd_h
old indirect symbol. Also used for copying flags to a weakdef. */
void
-_bfd_elf_link_hash_copy_indirect (const struct elf_backend_data *bed,
+_bfd_elf_link_hash_copy_indirect (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
- bfd_signed_vma tmp;
- bfd_signed_vma lowest_valid = bed->can_refcount;
+ struct elf_link_hash_table *htab;
/* Copy down any references that we may have already seen to the
symbol which just became indirect. */
@@ -1480,33 +1479,32 @@ _bfd_elf_link_hash_copy_indirect (const
/* Copy over the global and procedure linkage table refcount entries.
These may have been already set up by a check_relocs routine. */
- tmp = dir->got.refcount;
- if (tmp < lowest_valid)
+ htab = elf_hash_table (info);
+ if (ind->got.refcount > htab->init_got_refcount.refcount)
{
- dir->got.refcount = ind->got.refcount;
- ind->got.refcount = tmp;
+ if (dir->got.refcount < 0)
+ dir->got.refcount = 0;
+ dir->got.refcount += ind->got.refcount;
+ ind->got.refcount = htab->init_got_refcount.refcount;
}
- else
- BFD_ASSERT (ind->got.refcount < lowest_valid);
- tmp = dir->plt.refcount;
- if (tmp < lowest_valid)
+ if (ind->plt.refcount > htab->init_plt_refcount.refcount)
{
- dir->plt.refcount = ind->plt.refcount;
- ind->plt.refcount = tmp;
+ if (dir->plt.refcount < 0)
+ dir->plt.refcount = 0;
+ dir->plt.refcount += ind->plt.refcount;
+ ind->plt.refcount = htab->init_plt_refcount.refcount;
}
- else
- BFD_ASSERT (ind->plt.refcount < lowest_valid);
- if (dir->dynindx == -1)
+ if (ind->dynindx != -1)
{
+ if (dir->dynindx != -1)
+ _bfd_elf_strtab_delref (htab->dynstr, dir->dynstr_index);
dir->dynindx = ind->dynindx;
dir->dynstr_index = ind->dynstr_index;
ind->dynindx = -1;
ind->dynstr_index = 0;
}
- else
- BFD_ASSERT (ind->dynindx == -1);
}
void
Index: bfd/elf32-arm.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-arm.c,v
retrieving revision 1.59
diff -u -p -r1.59 elf32-arm.c
--- bfd/elf32-arm.c 19 Oct 2005 15:40:23 -0000 1.59
+++ bfd/elf32-arm.c 25 Oct 2005 12:59:21 -0000
@@ -1793,7 +1793,7 @@ elf32_arm_create_dynamic_sections (bfd *
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf32_arm_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf32_arm_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
@@ -1809,10 +1809,7 @@ elf32_arm_copy_indirect_symbol (const st
struct elf32_arm_relocs_copied **pp;
struct elf32_arm_relocs_copied *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->relocs_copied; (p = *pp) != NULL; )
{
@@ -1836,16 +1833,9 @@ elf32_arm_copy_indirect_symbol (const st
eind->relocs_copied = NULL;
}
- /* If the direct symbol already has an associated PLT entry, the
- indirect symbol should not. If it doesn't, swap refcount information
- from the indirect symbol. */
- if (edir->plt_thumb_refcount == 0)
- {
- edir->plt_thumb_refcount = eind->plt_thumb_refcount;
- eind->plt_thumb_refcount = 0;
- }
- else
- BFD_ASSERT (eind->plt_thumb_refcount == 0);
+ /* Copy over PLT info. */
+ edir->plt_thumb_refcount += eind->plt_thumb_refcount;
+ eind->plt_thumb_refcount = 0;
if (ind->root.type == bfd_link_hash_indirect
&& dir->got.refcount <= 0)
@@ -1854,7 +1844,7 @@ elf32_arm_copy_indirect_symbol (const st
eind->tls_type = GOT_UNKNOWN;
}
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
/* Create an ARM elf linker hash table. */
Index: bfd/elf32-hppa.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-hppa.c,v
retrieving revision 1.139
diff -u -p -r1.139 elf32-hppa.c
--- bfd/elf32-hppa.c 6 Oct 2005 19:21:13 -0000 1.139
+++ bfd/elf32-hppa.c 25 Oct 2005 12:59:23 -0000
@@ -1004,7 +1004,7 @@ elf32_hppa_create_dynamic_sections (bfd
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf32_hppa_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf32_hppa_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *eh_dir,
struct elf_link_hash_entry *eh_ind)
{
@@ -1020,16 +1020,15 @@ elf32_hppa_copy_indirect_symbol (const s
struct elf32_hppa_dyn_reloc_entry **hdh_pp;
struct elf32_hppa_dyn_reloc_entry *hdh_p;
- if (eh_ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (hdh_pp = &hh_ind->dyn_relocs; (hdh_p = *hdh_pp) != NULL; )
{
struct elf32_hppa_dyn_reloc_entry *hdh_q;
- for (hdh_q = hh_dir->dyn_relocs; hdh_q != NULL; hdh_q = hdh_q->hdh_next)
+ for (hdh_q = hh_dir->dyn_relocs;
+ hdh_q != NULL;
+ hdh_q = hdh_q->hdh_next)
if (hdh_q->sec == hdh_p->sec)
{
#if RELATIVE_DYNRELOCS
@@ -1062,7 +1061,7 @@ elf32_hppa_copy_indirect_symbol (const s
eh_dir->needs_plt |= eh_ind->needs_plt;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, eh_dir, eh_ind);
+ _bfd_elf_link_hash_copy_indirect (info, eh_dir, eh_ind);
}
/* Look through the relocs for a section during the first phase, and
Index: bfd/elf32-i386.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-i386.c,v
retrieving revision 1.149
diff -u -p -r1.149 elf32-i386.c
--- bfd/elf32-i386.c 31 Aug 2005 23:45:45 -0000 1.149
+++ bfd/elf32-i386.c 25 Oct 2005 12:59:25 -0000
@@ -772,7 +772,7 @@ elf_i386_create_dynamic_sections (bfd *d
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf_i386_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf_i386_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
@@ -788,10 +788,7 @@ elf_i386_copy_indirect_symbol (const str
struct elf_i386_dyn_relocs **pp;
struct elf_i386_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -836,7 +833,7 @@ elf_i386_copy_indirect_symbol (const str
dir->pointer_equality_needed |= ind->pointer_equality_needed;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
Index: bfd/elf32-m32r.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-m32r.c,v
retrieving revision 1.74
diff -u -p -r1.74 elf32-m32r.c
--- bfd/elf32-m32r.c 6 Oct 2005 19:21:13 -0000 1.74
+++ bfd/elf32-m32r.c 25 Oct 2005 12:59:27 -0000
@@ -1755,7 +1755,7 @@ m32r_elf_create_dynamic_sections (bfd *a
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-m32r_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+m32r_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
@@ -1772,10 +1772,7 @@ m32r_elf_copy_indirect_symbol (const str
struct elf_m32r_dyn_relocs **pp;
struct elf_m32r_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL;)
{
@@ -1799,7 +1796,7 @@ m32r_elf_copy_indirect_symbol (const str
eind->dyn_relocs = NULL;
}
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.182
diff -u -p -r1.182 elf32-ppc.c
--- bfd/elf32-ppc.c 24 Oct 2005 04:32:50 -0000 1.182
+++ bfd/elf32-ppc.c 25 Oct 2005 12:59:30 -0000
@@ -2565,12 +2565,11 @@ ppc_elf_create_dynamic_sections (bfd *ab
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-ppc_elf_copy_indirect_symbol (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
+ppc_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
struct ppc_elf_link_hash_entry *edir, *eind;
- bfd_signed_vma tmp;
edir = (struct ppc_elf_link_hash_entry *) dir;
eind = (struct ppc_elf_link_hash_entry *) ind;
@@ -2582,10 +2581,7 @@ ppc_elf_copy_indirect_symbol (const stru
struct ppc_elf_dyn_relocs **pp;
struct ppc_elf_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -2631,14 +2627,8 @@ ppc_elf_copy_indirect_symbol (const stru
/* Copy over the GOT refcount entries that we may have already seen to
the symbol which just became indirect. */
- tmp = edir->elf.got.refcount;
- if (tmp < 1)
- {
- edir->elf.got.refcount = eind->elf.got.refcount;
- eind->elf.got.refcount = tmp;
- }
- else
- BFD_ASSERT (eind->elf.got.refcount < 1);
+ edir->elf.got.refcount += eind->elf.got.refcount;
+ eind->elf.got.refcount = 0;
/* And plt entries. */
if (eind->elf.plt.plist != NULL)
@@ -2669,15 +2659,16 @@ ppc_elf_copy_indirect_symbol (const stru
eind->elf.plt.plist = NULL;
}
- if (edir->elf.dynindx == -1)
+ if (eind->elf.dynindx != -1)
{
+ if (edir->elf.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ edir->elf.dynstr_index);
edir->elf.dynindx = eind->elf.dynindx;
edir->elf.dynstr_index = eind->elf.dynstr_index;
eind->elf.dynindx = -1;
eind->elf.dynstr_index = 0;
}
- else
- BFD_ASSERT (eind->elf.dynindx == -1);
}
/* Return 1 if target is one of ours. */
Index: bfd/elf32-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-s390.c,v
retrieving revision 1.78
diff -u -p -r1.78 elf32-s390.c
--- bfd/elf32-s390.c 6 Oct 2005 19:21:14 -0000 1.78
+++ bfd/elf32-s390.c 25 Oct 2005 12:59:33 -0000
@@ -41,7 +41,7 @@ static bfd_boolean create_got_section
static bfd_boolean elf_s390_create_dynamic_sections
PARAMS((bfd *, struct bfd_link_info *));
static void elf_s390_copy_indirect_symbol
- PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *));
static bfd_boolean elf_s390_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -855,8 +855,8 @@ elf_s390_create_dynamic_sections (dynobj
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf_s390_copy_indirect_symbol (bed, dir, ind)
- const struct elf_backend_data *bed;
+elf_s390_copy_indirect_symbol (info, dir, ind)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *dir, *ind;
{
struct elf_s390_link_hash_entry *edir, *eind;
@@ -871,10 +871,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -918,7 +915,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
dir->needs_plt |= ind->needs_plt;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
Index: bfd/elf32-sh.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-sh.c,v
retrieving revision 1.130
diff -u -p -r1.130 elf32-sh.c
--- bfd/elf32-sh.c 6 Oct 2005 19:21:14 -0000 1.130
+++ bfd/elf32-sh.c 25 Oct 2005 12:59:35 -0000
@@ -6063,14 +6063,11 @@ sh_elf_gc_sweep_hook (bfd *abfd, struct
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-sh_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+sh_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
struct elf_sh_link_hash_entry *edir, *eind;
-#ifdef INCLUDE_SHMEDIA
- bfd_signed_vma tmp;
-#endif
edir = (struct elf_sh_link_hash_entry *) dir;
eind = (struct elf_sh_link_hash_entry *) ind;
@@ -6082,9 +6079,7 @@ sh_elf_copy_indirect_symbol (const struc
struct elf_sh_dyn_relocs **pp;
struct elf_sh_dyn_relocs *p;
- BFD_ASSERT (ind->root.type != bfd_link_hash_indirect);
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -6110,14 +6105,8 @@ sh_elf_copy_indirect_symbol (const struc
edir->gotplt_refcount = eind->gotplt_refcount;
eind->gotplt_refcount = 0;
#ifdef INCLUDE_SHMEDIA
- tmp = edir->datalabel_got.refcount;
- if (tmp < 1)
- {
- edir->datalabel_got.refcount = eind->datalabel_got.refcount;
- eind->datalabel_got.refcount = tmp;
- }
- else
- BFD_ASSERT (eind->datalabel_got.refcount < 1);
+ edir->datalabel_got.refcount += eind->datalabel_got.refcount;
+ eind->datalabel_got.refcount = 0;
#endif
if (ind->root.type == bfd_link_hash_indirect
@@ -6139,7 +6128,7 @@ sh_elf_copy_indirect_symbol (const struc
dir->needs_plt |= ind->needs_plt;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
Index: bfd/elf64-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-ppc.c,v
retrieving revision 1.224
diff -u -p -r1.224 elf64-ppc.c
--- bfd/elf64-ppc.c 23 Oct 2005 13:12:09 -0000 1.224
+++ bfd/elf64-ppc.c 25 Oct 2005 12:59:41 -0000
@@ -3844,10 +3844,9 @@ move_plt_plist (struct ppc_link_hash_ent
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-ppc64_elf_copy_indirect_symbol
- (const struct elf_backend_data *bed ATTRIBUTE_UNUSED,
- struct elf_link_hash_entry *dir,
- struct elf_link_hash_entry *ind)
+ppc64_elf_copy_indirect_symbol (struct bfd_link_info *info,
+ struct elf_link_hash_entry *dir,
+ struct elf_link_hash_entry *ind)
{
struct ppc_link_hash_entry *edir, *eind;
@@ -3862,10 +3861,7 @@ ppc64_elf_copy_indirect_symbol
struct ppc_dyn_relocs **pp;
struct ppc_dyn_relocs *p;
- if (eind->elf.root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -3945,15 +3941,16 @@ ppc64_elf_copy_indirect_symbol
/* And plt entries. */
move_plt_plist (eind, edir);
- if (edir->elf.dynindx == -1)
+ if (eind->elf.dynindx != -1)
{
+ if (edir->elf.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ edir->elf.dynstr_index);
edir->elf.dynindx = eind->elf.dynindx;
edir->elf.dynstr_index = eind->elf.dynstr_index;
eind->elf.dynindx = -1;
eind->elf.dynstr_index = 0;
}
- else
- BFD_ASSERT (eind->elf.dynindx == -1);
}
/* Find the function descriptor hash entry from the given function code
Index: bfd/elf64-s390.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-s390.c,v
retrieving revision 1.78
diff -u -p -r1.78 elf64-s390.c
--- bfd/elf64-s390.c 6 Oct 2005 19:21:14 -0000 1.78
+++ bfd/elf64-s390.c 25 Oct 2005 12:59:43 -0000
@@ -41,7 +41,7 @@ static bfd_boolean create_got_section
static bfd_boolean elf_s390_create_dynamic_sections
PARAMS((bfd *, struct bfd_link_info *));
static void elf_s390_copy_indirect_symbol
- PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *));
static bfd_boolean elf_s390_check_relocs
PARAMS ((bfd *, struct bfd_link_info *, asection *,
@@ -808,8 +808,8 @@ elf_s390_create_dynamic_sections (dynobj
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf_s390_copy_indirect_symbol (bed, dir, ind)
- const struct elf_backend_data *bed;
+elf_s390_copy_indirect_symbol (info, dir, ind)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *dir, *ind;
{
struct elf_s390_link_hash_entry *edir, *eind;
@@ -824,10 +824,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
struct elf_s390_dyn_relocs **pp;
struct elf_s390_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -871,7 +868,7 @@ elf_s390_copy_indirect_symbol (bed, dir,
dir->needs_plt |= ind->needs_plt;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
Index: bfd/elf64-x86-64.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-x86-64.c,v
retrieving revision 1.107
diff -u -p -r1.107 elf64-x86-64.c
--- bfd/elf64-x86-64.c 31 Aug 2005 23:45:46 -0000 1.107
+++ bfd/elf64-x86-64.c 25 Oct 2005 12:59:44 -0000
@@ -525,7 +525,7 @@ elf64_x86_64_create_dynamic_sections (bf
/* Copy the extra info we tack onto an elf_link_hash_entry. */
static void
-elf64_x86_64_copy_indirect_symbol (const struct elf_backend_data *bed,
+elf64_x86_64_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
@@ -541,10 +541,7 @@ elf64_x86_64_copy_indirect_symbol (const
struct elf64_x86_64_dyn_relocs **pp;
struct elf64_x86_64_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -589,7 +586,7 @@ elf64_x86_64_copy_indirect_symbol (const
dir->pointer_equality_needed |= ind->pointer_equality_needed;
}
else
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static bfd_boolean
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.195
diff -u -p -r1.195 elflink.c
--- bfd/elflink.c 24 Oct 2005 11:24:31 -0000 1.195
+++ bfd/elflink.c 25 Oct 2005 12:59:50 -0000
@@ -1283,7 +1283,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
flip->root.type = h->root.type;
h->root.type = bfd_link_hash_indirect;
h->root.u.i.link = (struct bfd_link_hash_entry *) flip;
- (*bed->elf_backend_copy_indirect_symbol) (bed, flip, h);
+ (*bed->elf_backend_copy_indirect_symbol) (info, flip, h);
flip->root.u.undef.abfd = h->root.u.undef.abfd;
if (h->def_dynamic)
{
@@ -1437,7 +1437,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
struct elf_link_hash_entry *ht;
ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
- (*bed->elf_backend_copy_indirect_symbol) (bed, ht, hi);
+ (*bed->elf_backend_copy_indirect_symbol) (info, ht, hi);
/* See if the new flags lead us to realize that the symbol must
be dynamic. */
@@ -1506,7 +1506,7 @@ nondefault:
if (hi->root.type == bfd_link_hash_indirect)
{
- (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
/* See if the new flags lead us to realize that the symbol
must be dynamic. */
@@ -2317,7 +2317,7 @@ _bfd_elf_fix_symbol_flags (struct elf_li
const struct elf_backend_data *bed;
bed = get_elf_backend_data (elf_hash_table (eif->info)->dynobj);
- (*bed->elf_backend_copy_indirect_symbol) (bed, weakdef, h);
+ (*bed->elf_backend_copy_indirect_symbol) (eif->info, weakdef, h);
}
}
@@ -4139,7 +4139,7 @@ elf_link_add_object_symbols (bfd *abfd,
(*bed->elf_backend_hide_symbol) (info, hi, TRUE);
hi->root.type = bfd_link_hash_indirect;
hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
- (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+ (*bed->elf_backend_copy_indirect_symbol) (info, h, hi);
sym_hash = elf_sym_hashes (abfd);
if (sym_hash)
for (symidx = 0; symidx < extsymcount; ++symidx)
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.174
diff -u -p -r1.174 elfxx-ia64.c
--- bfd/elfxx-ia64.c 9 Sep 2005 05:11:51 -0000 1.174
+++ bfd/elfxx-ia64.c 25 Oct 2005 12:59:53 -0000
@@ -216,7 +216,7 @@ static struct bfd_hash_entry *elfNN_ia64
PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
const char *string));
static void elfNN_ia64_hash_copy_indirect
- PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
+ PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *));
static void elfNN_ia64_hash_hide_symbol
PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
@@ -1798,8 +1798,8 @@ elfNN_ia64_new_elf_hash_entry (entry, ta
}
static void
-elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
- const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
+elfNN_ia64_hash_copy_indirect (info, xdir, xind)
+ struct bfd_link_info *info;
struct elf_link_hash_entry *xdir, *xind;
{
struct elfNN_ia64_link_hash_entry *dir, *ind;
@@ -1821,29 +1821,34 @@ elfNN_ia64_hash_copy_indirect (bed, xdir
/* Copy over the got and plt data. This would have been done
by check_relocs. */
- if (dir->info == NULL)
+ if (ind->info != NULL)
{
struct elfNN_ia64_dyn_sym_info *dyn_i;
+ struct elfNN_ia64_dyn_sym_info **pdyn;
- dir->info = dyn_i = ind->info;
+ pdyn = &dir->info;
+ while ((dyn_i = *pdyn) != NULL)
+ pdyn = &dyn_i->next;
+ *pdyn = dyn_i = ind->info;
ind->info = NULL;
/* Fix up the dyn_sym_info pointers to the global symbol. */
for (; dyn_i; dyn_i = dyn_i->next)
dyn_i->h = &dir->root;
}
- BFD_ASSERT (ind->info == NULL);
/* Copy over the dynindx. */
- if (dir->root.dynindx == -1)
+ if (ind->root.dynindx != -1)
{
+ if (dir->root.dynindx != -1)
+ _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
+ dir->root.dynstr_index);
dir->root.dynindx = ind->root.dynindx;
dir->root.dynstr_index = ind->root.dynstr_index;
ind->root.dynindx = -1;
ind->root.dynstr_index = 0;
}
- BFD_ASSERT (ind->root.dynindx == -1);
}
static void
Index: bfd/elfxx-mips.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.c,v
retrieving revision 1.151
diff -u -p -r1.151 elfxx-mips.c
--- bfd/elfxx-mips.c 6 Oct 2005 19:21:14 -0000 1.151
+++ bfd/elfxx-mips.c 25 Oct 2005 12:59:58 -0000
@@ -8387,13 +8387,13 @@ _bfd_mips_elf_gc_sweep_hook (bfd *abfd A
_bfd_elf_link_hash_copy_indirect copy the flags for us. */
void
-_bfd_mips_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+_bfd_mips_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
struct mips_elf_link_hash_entry *dirmips, *indmips;
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
if (ind->root.type != bfd_link_hash_indirect)
return;
@@ -8408,8 +8408,6 @@ _bfd_mips_elf_copy_indirect_symbol (cons
if (dirmips->tls_type == 0)
dirmips->tls_type = indmips->tls_type;
- else
- BFD_ASSERT (indmips->tls_type == 0);
}
void
Index: bfd/elfxx-mips.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-mips.h,v
retrieving revision 1.29
diff -u -p -r1.29 elfxx-mips.h
--- bfd/elfxx-mips.h 8 Jul 2005 00:26:53 -0000 1.29
+++ bfd/elfxx-mips.h 25 Oct 2005 12:59:59 -0000
@@ -72,7 +72,7 @@ extern asection * _bfd_mips_elf_gc_mark_
extern bfd_boolean _bfd_mips_elf_gc_sweep_hook
(bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
extern void _bfd_mips_elf_copy_indirect_symbol
- (const struct elf_backend_data *, struct elf_link_hash_entry *,
+ (struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern void _bfd_mips_elf_hide_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean);
Index: bfd/elfxx-sparc.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.c,v
retrieving revision 1.14
diff -u -p -r1.14 elfxx-sparc.c
--- bfd/elfxx-sparc.c 6 Oct 2005 19:21:14 -0000 1.14
+++ bfd/elfxx-sparc.c 25 Oct 2005 13:00:00 -0000
@@ -881,7 +881,7 @@ _bfd_sparc_elf_create_dynamic_sections (
/* Copy the extra info we tack onto an elf_link_hash_entry. */
void
-_bfd_sparc_elf_copy_indirect_symbol (const struct elf_backend_data *bed,
+_bfd_sparc_elf_copy_indirect_symbol (struct bfd_link_info *info,
struct elf_link_hash_entry *dir,
struct elf_link_hash_entry *ind)
{
@@ -897,10 +897,7 @@ _bfd_sparc_elf_copy_indirect_symbol (con
struct _bfd_sparc_elf_dyn_relocs **pp;
struct _bfd_sparc_elf_dyn_relocs *p;
- if (ind->root.type == bfd_link_hash_indirect)
- abort ();
-
- /* Add reloc counts against the weak sym to the strong sym
+ /* Add reloc counts against the indirect sym to the direct sym
list. Merge any entries against the same section. */
for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
{
@@ -930,7 +927,7 @@ _bfd_sparc_elf_copy_indirect_symbol (con
edir->tls_type = eind->tls_type;
eind->tls_type = GOT_UNKNOWN;
}
- _bfd_elf_link_hash_copy_indirect (bed, dir, ind);
+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
}
static int
Index: bfd/elfxx-sparc.h
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-sparc.h,v
retrieving revision 1.4
diff -u -p -r1.4 elfxx-sparc.h
--- bfd/elfxx-sparc.h 4 May 2005 15:53:31 -0000 1.4
+++ bfd/elfxx-sparc.h 25 Oct 2005 13:00:00 -0000
@@ -97,7 +97,7 @@ extern struct bfd_link_hash_table *_bfd_
extern bfd_boolean _bfd_sparc_elf_create_dynamic_sections
(bfd *, struct bfd_link_info *);
extern void _bfd_sparc_elf_copy_indirect_symbol
- (const struct elf_backend_data *,
+ (struct bfd_link_info *,
struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern bfd_boolean _bfd_sparc_elf_check_relocs
--
Alan Modra
IBM OzLabs - Linux Technology Centre