* elflink.h (elf_bfd_final_link): Assert that section reloc_count

field equals the new rel_count field.
	(elf_link_input_bfd): When doing a relocateable link, use the new
	rel_count field rather than the reloc_count field.
	(elf_reloc_link_order): Likewise.
	(elf_finish_pointer_linker_section): Likewise.
	Based on patch from H.J. Lu <hjl@gnu.org>:
	* elflink.h (elf_merge_symbol): Permit a non-weak definition in a
	shared library to override a weak definition in a regular object.
This commit is contained in:
Ian Lance Taylor 1999-07-07 11:39:43 +00:00
parent cac58fa6ef
commit 0525d26ec3
2 changed files with 60 additions and 11 deletions

View File

@ -1,3 +1,16 @@
1999-07-07 Ian Lance Taylor <ian@zembu.com>
* elflink.h (elf_bfd_final_link): Assert that section reloc_count
field equals the new rel_count field.
(elf_link_input_bfd): When doing a relocateable link, use the new
rel_count field rather than the reloc_count field.
(elf_reloc_link_order): Likewise.
(elf_finish_pointer_linker_section): Likewise.
Based on patch from H.J. Lu <hjl@gnu.org>:
* elflink.h (elf_merge_symbol): Permit a non-weak definition in a
shared library to override a weak definition in a regular object.
Tue Jul 6 10:23:39 1999 Jeffrey A Law (law@cygnus.com)
* libhppa.h: Revert July 2, 1999 patch.

View File

@ -492,14 +492,19 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
represent variables; this can cause confusion in principle, but
any such confusion would seem to indicate an erroneous program or
shared library. We also permit a common symbol in a regular
object to override a weak symbol in a shared object. */
object to override a weak symbol in a shared object.
We prefer a non-weak definition in a shared library to a weak
definition in the executable. */
if (newdyn
&& newdef
&& (olddef
|| (h->root.type == bfd_link_hash_common
&& (bind == STB_WEAK
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
|| ELF_ST_TYPE (sym->st_info) == STT_FUNC)))
&& (h->root.type != bfd_link_hash_defweak
|| bind == STB_WEAK))
{
*override = true;
newdef = false;
@ -543,7 +548,10 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
As above, we again permit a common symbol in a regular object to
override a definition in a shared object if the shared object
symbol is a function or is weak. */
symbol is a function or is weak.
As above, we permit a non-weak definition in a shared object to
override a weak definition in a regular object. */
if (! newdyn
&& (newdef
@ -552,7 +560,9 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
|| h->type == STT_FUNC)))
&& olddyn
&& olddef
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
&& (bind != STB_WEAK
|| h->root.type == bfd_link_hash_defweak))
{
/* Change the hash table entry to undefined, and let
_bfd_generic_link_add_one_symbol do the right thing with the
@ -626,6 +636,31 @@ elf_merge_symbol (abfd, info, name, sym, psec, pvalue, sym_hash,
h->verinfo.vertree = NULL;
}
/* Handle the special case of a weak definition in a regular object
followed by a non-weak definition in a shared object. In this
case, we prefer the definition in the shared object. To make
this work we have to frob the flags. */
if (olddef
&& ! olddyn
&& h->root.type == bfd_link_hash_defweak
&& newdef
&& newdyn
&& bind != STB_WEAK)
h->elf_link_hash_flags &= ~ ELF_LINK_HASH_DEF_REGULAR;
/* Handle the special case of a non-weak definition in a shared
object followed by a weak definition in a regular object. In
this case we prefer to definition in the shared object. To make
this work we have to tell the caller to not treat the new symbol
as a definition. */
if (olddef
&& olddyn
&& h->root.type != bfd_link_hash_defweak
&& newdef
&& ! newdyn
&& bind == STB_WEAK)
*override = true;
return true;
}
@ -4139,6 +4174,7 @@ elf_bfd_final_link (abfd, info)
rel_hash = elf_section_data (o)->rel_hashes;
rel_hdr = &elf_section_data (o)->rel_hdr;
BFD_ASSERT (elf_section_data (o)->rel_count == o->reloc_count);
for (i = 0; i < o->reloc_count; i++, rel_hash++)
{
if (*rel_hash == NULL)
@ -5087,7 +5123,7 @@ elf_link_input_bfd (finfo, input_bfd)
irela = internal_relocs;
irelaend = irela + o->reloc_count;
rel_hash = (elf_section_data (o->output_section)->rel_hashes
+ o->output_section->reloc_count);
+ elf_section_data (o->output_section)->rel_count);
for (; irela < irelaend; irela++, rel_hash++)
{
unsigned long r_symndx;
@ -5277,7 +5313,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
/* Figure out the symbol index. */
rel_hash_ptr = (elf_section_data (output_section)->rel_hashes
+ output_section->reloc_count);
+ elf_section_data (output_section)->rel_count);
if (link_order->type == bfd_section_reloc_link_order)
{
indx = link_order->u.reloc.p->u.section->target_index;
@ -5386,7 +5422,7 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
irel.r_offset = offset;
irel.r_info = ELF_R_INFO (indx, howto->type);
erel = ((Elf_External_Rel *) rel_hdr->contents
+ output_section->reloc_count);
+ elf_section_data (output_section)->rel_count);
elf_swap_reloc_out (output_bfd, &irel, erel);
}
else
@ -5398,11 +5434,11 @@ elf_reloc_link_order (output_bfd, info, output_section, link_order)
irela.r_info = ELF_R_INFO (indx, howto->type);
irela.r_addend = addend;
erela = ((Elf_External_Rela *) rel_hdr->contents
+ output_section->reloc_count);
+ elf_section_data (output_section)->rel_count);
elf_swap_reloca_out (output_bfd, &irela, erela);
}
++output_section->reloc_count;
++elf_section_data (output_section)->rel_count;
return true;
}
@ -5622,8 +5658,8 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, reloca
elf_swap_reloca_out (output_bfd, &outrel,
(((Elf_External_Rela *)
lsect->section->contents)
+ lsect->section->reloc_count));
++lsect->section->reloc_count;
+ elf_section_data (lsect->section)->rel_count));
++elf_section_data (lsect->section)->rel_count;
}
}
}