aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@airs.com>1995-08-14 15:57:17 +0000
committerIan Lance Taylor <ian@airs.com>1995-08-14 15:57:17 +0000
commit452a5efbaf30e9ec7a7892716294ebdb02837c7f (patch)
tree3a77c5f76fd3ee63f90adaf321bf2c52336a363f /bfd
parent5c800455bf7f27ad0e11e896f4bf44eeff29c829 (diff)
downloadgdb-452a5efbaf30e9ec7a7892716294ebdb02837c7f.zip
gdb-452a5efbaf30e9ec7a7892716294ebdb02837c7f.tar.gz
gdb-452a5efbaf30e9ec7a7892716294ebdb02837c7f.tar.bz2
* 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.
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog23
-rw-r--r--bfd/elf32-i386.c52
-rw-r--r--bfd/elflink.h28
3 files changed, 84 insertions, 19 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 13270c1..789137a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -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.
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index a362262..e206516 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -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));
diff --git a/bfd/elflink.h b/bfd/elflink.h
index ecacfbb..07ab9bb 100644
--- a/bfd/elflink.h
+++ b/bfd/elflink.h
@@ -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