* elflink.h (elf_link_add_object_symbols): If a symbol is a weak

definition, add it to the dynamic symbol table if any dynamic
	object mentions it.  If we do add it, make sure we add the
	corresponding real symbol.
	(elf_adjust_dynamic_symbol): Adjust a weak defined symbol which we
	put in the dynamic symbol table, even if no regular object refers
	to it.
	* elf32-i386.c (elf_i386_check_relocs): When creating a shared
	library, don't allocate space for a PC relative reloc against a
	local symbol.
	* elf32-m68k.c (elf_m68k_check_relocs): Likewise.
	* elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
	* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Change assertion
	to accept symbol with weakdef set.
	* elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
	* elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
	* elf32-m68k.c (elf_m68k_relocate_section): When creating a shared
	libary, don't copy over a PC relative reloc against a local
	symbol.
	* elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
PR 7711.
This commit is contained in:
Ian Lance Taylor 1995-08-14 15:57:17 +00:00
parent 5c800455bf
commit 452a5efbaf
3 changed files with 84 additions and 19 deletions

View File

@ -1,3 +1,26 @@
Mon Aug 14 11:39:24 1995 Ian Lance Taylor <ian@cygnus.com>
* elflink.h (elf_link_add_object_symbols): If a symbol is a weak
definition, add it to the dynamic symbol table if any dynamic
object mentions it. If we do add it, make sure we add the
corresponding real symbol.
(elf_adjust_dynamic_symbol): Adjust a weak defined symbol which we
put in the dynamic symbol table, even if no regular object refers
to it.
* elf32-i386.c (elf_i386_check_relocs): When creating a shared
library, don't allocate space for a PC relative reloc against a
local symbol.
* elf32-m68k.c (elf_m68k_check_relocs): Likewise.
* elf32-sparc.c (elf32_sparc_check_relocs): Likewise.
* elf32-i386.c (elf_i386_adjust_dynamic_symbol): Change assertion
to accept symbol with weakdef set.
* elf32-m68k.c (elf_m68k_adjust_dynamic_symbol): Likewise.
* elf32-sparc.c (elf32_sparc_adjust_dynamic_symbol): Likewise.
* elf32-m68k.c (elf_m68k_relocate_section): When creating a shared
libary, don't copy over a PC relative reloc against a local
symbol.
* elf32-sparc.c (elf32_sparc_relocate_section): Likewise.
Sun Aug 13 00:40:58 1995 Jeff Law (law@snake.cs.utah.edu) Sun Aug 13 00:40:58 1995 Jeff Law (law@snake.cs.utah.edu)
* som.h (R_HPPA_BEGIN_BRTAB): Define. * som.h (R_HPPA_BEGIN_BRTAB): Define.

View File

@ -417,7 +417,8 @@ elf_i386_check_relocs (abfd, info, sec, relocs)
case R_386_32: case R_386_32:
case R_386_PC32: case R_386_PC32:
if (info->shared if (info->shared
&& (sec->flags & SEC_ALLOC) != 0) && (sec->flags & SEC_ALLOC) != 0
&& (r_type != R_386_PC32 || h != NULL))
{ {
/* When creating a shared object, we must copy these /* When creating a shared object, we must copy these
reloc types into the output file. We create a reloc reloc types into the output file. We create a reloc
@ -486,6 +487,7 @@ elf_i386_adjust_dynamic_symbol (info, h)
/* Make sure we know what is going on here. */ /* Make sure we know what is going on here. */
BFD_ASSERT (dynobj != NULL BFD_ASSERT (dynobj != NULL
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) && ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
|| h->weakdef != NULL
|| ((h->elf_link_hash_flags || ((h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_DYNAMIC) != 0 & ELF_LINK_HASH_DEF_DYNAMIC) != 0
&& (h->elf_link_hash_flags && (h->elf_link_hash_flags
@ -909,7 +911,11 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
|| (r_type == R_386_PLT32 || (r_type == R_386_PLT32
&& h->plt_offset != (bfd_vma) -1) && h->plt_offset != (bfd_vma) -1)
|| (r_type == R_386_GOT32 || (r_type == R_386_GOT32
&& elf_hash_table (info)->dynamic_sections_created) && elf_hash_table (info)->dynamic_sections_created
&& (! info->shared
|| ! info->symbolic
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) == 0))
|| (info->shared || (info->shared
&& (r_type == R_386_32 && (r_type == R_386_32
|| r_type == R_386_PC32) || r_type == R_386_PC32)
@ -927,7 +933,7 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
} }
else if (h->root.type == bfd_link_hash_undefweak) else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0; relocation = 0;
else if (info->shared) else if (info->shared && !info->symbolic)
relocation = 0; relocation = 0;
else else
{ {
@ -957,13 +963,18 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
off = h->got_offset; off = h->got_offset;
BFD_ASSERT (off != (bfd_vma) -1); BFD_ASSERT (off != (bfd_vma) -1);
if (! elf_hash_table (info)->dynamic_sections_created) if (! elf_hash_table (info)->dynamic_sections_created
|| (info->shared
&& info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{ {
/* This is actually a static link. We must /* This is actually a static link, or it is a
initialize this entry in the global offset table. -Bsymbolic link and the symbol is defined
Since the offset must always be a multiple of 4, locally. We must initialize this entry in the
we use the least significant bit to record global offset table. Since the offset must
whether we have initialized it already. always be a multiple of 4, we use the least
significant bit to record whether we have
initialized it already.
When doing a dynamic link, we create a .rel.got When doing a dynamic link, we create a .rel.got
relocation entry to initialize the value. This relocation entry to initialize the value. This
@ -1069,7 +1080,8 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
if (h->plt_offset == (bfd_vma) -1) if (h->plt_offset == (bfd_vma) -1)
{ {
/* We didn't make a PLT entry for this symbol. This /* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code. */ happens when statically linking PIC code, or when
using -Bsymbolic. */
break; break;
} }
@ -1304,12 +1316,24 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
srel = bfd_get_section_by_name (dynobj, ".rel.got"); srel = bfd_get_section_by_name (dynobj, ".rel.got");
BFD_ASSERT (sgot != NULL && srel != NULL); BFD_ASSERT (sgot != NULL && srel != NULL);
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
rel.r_offset = (sgot->output_section->vma rel.r_offset = (sgot->output_section->vma
+ sgot->output_offset + sgot->output_offset
+ h->got_offset); + (h->got_offset &~ 1));
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
/* If this is a -Bsymbolic link, and the symbol is defined
locally, we just want to emit a RELATIVE reloc. The entry in
the global offset table will already have been initialized in
the relocate_section function. */
if (info->shared
&& info->symbolic
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
rel.r_info = ELF32_R_INFO (0, R_386_RELATIVE);
else
{
bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents + h->got_offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
}
bfd_elf32_swap_reloc_out (output_bfd, &rel, bfd_elf32_swap_reloc_out (output_bfd, &rel,
((Elf32_External_Rel *) srel->contents ((Elf32_External_Rel *) srel->contents
+ srel->reloc_count)); + srel->reloc_count));

View File

@ -16,6 +16,7 @@ GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ELF linker code. */ /* ELF linker code. */
static boolean elf_link_add_object_symbols static boolean elf_link_add_object_symbols
@ -507,6 +508,7 @@ elf_link_add_object_symbols (abfd, info)
const char *name; const char *name;
struct elf_link_hash_entry *h = NULL; struct elf_link_hash_entry *h = NULL;
boolean definition; boolean definition;
boolean new_weakdef;
elf_swap_symbol_in (abfd, esym, &sym); elf_swap_symbol_in (abfd, esym, &sym);
@ -646,6 +648,7 @@ elf_link_add_object_symbols (abfd, info)
false, collect, (struct bfd_link_hash_entry **) sym_hash))) false, collect, (struct bfd_link_hash_entry **) sym_hash)))
goto error_return; goto error_return;
new_weakdef = false;
if (dynamic if (dynamic
&& definition && definition
&& (flags & BSF_WEAK) != 0 && (flags & BSF_WEAK) != 0
@ -667,6 +670,7 @@ elf_link_add_object_symbols (abfd, info)
(*sym_hash)->weakdef = weaks; (*sym_hash)->weakdef = weaks;
weaks = *sym_hash; weaks = *sym_hash;
new_weakdef = true;
} }
/* Get the alignment of a common symbol. */ /* Get the alignment of a common symbol. */
@ -721,7 +725,10 @@ elf_link_add_object_symbols (abfd, info)
new_flag = ELF_LINK_HASH_DEF_DYNAMIC; new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
if ((old_flags & new_flag) != 0 if ((old_flags & new_flag) != 0
|| (old_flags & (ELF_LINK_HASH_DEF_REGULAR || (old_flags & (ELF_LINK_HASH_DEF_REGULAR
| ELF_LINK_HASH_REF_REGULAR)) != 0) | ELF_LINK_HASH_REF_REGULAR)) != 0
|| (h->weakdef != NULL
&& (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
| ELF_LINK_HASH_REF_DYNAMIC)) != 0))
dynsym = true; dynsym = true;
} }
@ -730,6 +737,14 @@ elf_link_add_object_symbols (abfd, info)
{ {
if (! _bfd_elf_link_record_dynamic_symbol (info, h)) if (! _bfd_elf_link_record_dynamic_symbol (info, h))
goto error_return; goto error_return;
if (h->weakdef != NULL
&& ! new_weakdef
&& h->weakdef->dynindx == -1)
{
if (! _bfd_elf_link_record_dynamic_symbol (info,
h->weakdef))
goto error_return;
}
} }
} }
} }
@ -1432,13 +1447,16 @@ elf_adjust_dynamic_symbol (h, data)
/* If this symbol does not require a PLT entry, and it is not /* If this symbol does not require a PLT entry, and it is not
defined by a dynamic object, or is not referenced by a regular defined by a dynamic object, or is not referenced by a regular
object, ignore it. FIXME: Do we need to worry about symbols object, ignore it. We do have to handle a weak defined symbol,
which are defined by one dynamic object and referenced by another even if no regular object refers to it, if we decided to add it
one? */ to the dynamic symbol table. FIXME: Do we normally need to worry
about symbols which are defined by one dynamic object and
referenced by another one? */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0 if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT) == 0
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0 && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
|| (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0 || (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
|| (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0)) || ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
&& (h->weakdef == NULL || h->weakdef->dynindx == -1))))
return true; return true;
/* If we've already adjusted this symbol, don't do it again. This /* If we've already adjusted this symbol, don't do it again. This