diff options
author | Ian Lance Taylor <ian@airs.com> | 1995-08-14 15:57:17 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@airs.com> | 1995-08-14 15:57:17 +0000 |
commit | 452a5efbaf30e9ec7a7892716294ebdb02837c7f (patch) | |
tree | 3a77c5f76fd3ee63f90adaf321bf2c52336a363f /bfd/elf32-i386.c | |
parent | 5c800455bf7f27ad0e11e896f4bf44eeff29c829 (diff) | |
download | gdb-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/elf32-i386.c')
-rw-r--r-- | bfd/elf32-i386.c | 52 |
1 files changed, 38 insertions, 14 deletions
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)); |