* 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)
* 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_PC32:
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
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. */
BFD_ASSERT (dynobj != NULL
&& ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_PLT)
|| h->weakdef != NULL
|| ((h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_DYNAMIC) != 0
&& (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
&& h->plt_offset != (bfd_vma) -1)
|| (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
&& (r_type == R_386_32
|| 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)
relocation = 0;
else if (info->shared)
else if (info->shared && !info->symbolic)
relocation = 0;
else
{
@ -957,13 +963,18 @@ elf_i386_relocate_section (output_bfd, info, input_bfd, input_section,
off = h->got_offset;
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
initialize this entry in the global offset table.
Since the offset must always be a multiple of 4,
we use the least significant bit to record
whether we have initialized it already.
/* This is actually a static link, or it is a
-Bsymbolic link and the symbol is defined
locally. We must initialize this entry in the
global offset table. Since the offset must
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
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)
{
/* 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;
}
@ -1304,12 +1316,24 @@ elf_i386_finish_dynamic_symbol (output_bfd, info, h, sym)
srel = bfd_get_section_by_name (dynobj, ".rel.got");
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
+ sgot->output_offset
+ h->got_offset);
rel.r_info = ELF32_R_INFO (h->dynindx, R_386_GLOB_DAT);
+ (h->got_offset &~ 1));
/* 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,
((Elf32_External_Rel *) srel->contents
+ 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
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
/* ELF linker code. */
static boolean elf_link_add_object_symbols
@ -507,6 +508,7 @@ elf_link_add_object_symbols (abfd, info)
const char *name;
struct elf_link_hash_entry *h = NULL;
boolean definition;
boolean new_weakdef;
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)))
goto error_return;
new_weakdef = false;
if (dynamic
&& definition
&& (flags & BSF_WEAK) != 0
@ -667,6 +670,7 @@ elf_link_add_object_symbols (abfd, info)
(*sym_hash)->weakdef = weaks;
weaks = *sym_hash;
new_weakdef = true;
}
/* 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;
if ((old_flags & new_flag) != 0
|| (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;
}
@ -730,6 +737,14 @@ elf_link_add_object_symbols (abfd, info)
{
if (! _bfd_elf_link_record_dynamic_symbol (info, h))
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
defined by a dynamic object, or is not referenced by a regular
object, ignore it. FIXME: Do we need to worry about symbols
which are defined by one dynamic object and referenced by another
one? */
object, ignore it. We do have to handle a weak defined symbol,
even if no regular object refers to it, if we decided to add it
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
&& ((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_REF_REGULAR) == 0))
|| ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0
&& (h->weakdef == NULL || h->weakdef->dynindx == -1))))
return true;
/* If we've already adjusted this symbol, don't do it again. This