+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.
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
/* 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
|| (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)
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (info->shared)
+ else if (info->shared && !info->symbolic)
relocation = 0;
else
{
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
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;
}
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));
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
const char *name;
struct elf_link_hash_entry *h = NULL;
boolean definition;
+ boolean new_weakdef;
elf_swap_symbol_in (abfd, esym, &sym);
false, collect, (struct bfd_link_hash_entry **) sym_hash)))
goto error_return;
+ new_weakdef = false;
if (dynamic
&& definition
&& (flags & BSF_WEAK) != 0
(*sym_hash)->weakdef = weaks;
weaks = *sym_hash;
+ new_weakdef = true;
}
/* Get the alignment of a common symbol. */
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;
}
{
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;
+ }
}
}
}
/* 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