* 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:
parent
cac58fa6ef
commit
0525d26ec3
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue