* 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:
parent
5c800455bf
commit
452a5efbaf
|
@ -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.
|
||||||
|
|
|
@ -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));
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue