From: Andreas Jaeger Date: Sun, 29 Apr 2001 13:42:45 +0000 (+0000) Subject: * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Only swap X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=053579d75409784648605b6d5876860598909fab;p=binutils-gdb.git * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Only swap out handled entries. (elf64_x86_64_finish_dynamic_symbol): Set up GOT entries. (elf64_x86_64_relocate_section): Fix GOTPCREL calculation. (elf64_x86_64_relocate_section): Merge entries for GOTPCREL and GOT32. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 4e3860d5692..f9cc5e38d80 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,12 @@ +2001-04-27 Andreas Jaeger + + * elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Only swap + out handled entries. + (elf64_x86_64_finish_dynamic_symbol): Set up GOT entries. + (elf64_x86_64_relocate_section): Fix GOTPCREL calculation. + (elf64_x86_64_relocate_section): Merge entries for GOTPCREL and + GOT32. + 2001-04-27 Sean McNeil * config.bfd: Add arm-vxworks target. @@ -48,12 +57,12 @@ (cpu-openrisc.lo, elf32-openrisc.lo): New rules. * Makefile.in: Regenerated. * config.bfd: (openrisc-*-elf): New target. - * configure.in (bfd_elf32_openrisc_vec): New vector. + * configure.in (bfd_elf32_openrisc_vec): New vector. * configure: Regenerated. * libbfd.h: Regenerated. * bfd-in2.h: Regenerated. * reloc.c: Add OpenRISC relocations. - * targets.c (bfd_elf32_openrisc_vec): Declare. + * targets.c (bfd_elf32_openrisc_vec): Declare. (bfd_target_vect): Add bfd_elf32_openrisc_vec. * archures.c (enum bfd_architecture): Add bfd_arch_openrisc. (bfd_openrisc_arch): Declare. diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 912f666bfba..f23e06cdb13 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -1321,92 +1321,10 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, case R_X86_64_GOT32: /* Relocation is to the entry for this symbol in the global offset table. */ - BFD_ASSERT (sgot != NULL); - - if (h != NULL) - { - bfd_vma off = h->got.offset; - BFD_ASSERT (off != (bfd_vma) -1); - - if (! elf_hash_table (info)->dynamic_sections_created - || (info->shared - && (info->symbolic || h->dynindx == -1) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) - { - /* This is actually a static link, or it is a -Bsymbolic - link and the symbol is defined locally, or the symbol - was forced to be local because of a version file. We - must initialize this entry in the global offset table. - Since the offset must always be a multiple of 8, we - use the least significant bit to record whether we - have initialized it already. - - When doing a dynamic link, we create a .rela.got - relocation entry to initialize the value. This is - done in the finish_dynamic_symbol routine. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_64 (output_bfd, relocation, - sgot->contents + off); - h->got.offset |= 1; - } - } - relocation = sgot->output_offset + off; - } - else - { - bfd_vma off; - - BFD_ASSERT (local_got_offsets != NULL - && local_got_offsets[r_symndx] != (bfd_vma) -1); - - off = local_got_offsets[r_symndx]; - - /* The offset must always be a multiple of 8. We use - the least significant bit to record whether we have - already generated the necessary reloc. */ - if ((off & 1) != 0) - off &= ~1; - else - { - bfd_put_64 (output_bfd, relocation, sgot->contents + off); - - if (info->shared) - { - asection *srelgot; - Elf_Internal_Rela outrel; - - /* We need to generate a R_X86_64_RELATIVE reloc - for the dynamic linker. */ - srelgot = bfd_get_section_by_name (dynobj, ".rela.got"); - BFD_ASSERT (srelgot != NULL); - - outrel.r_offset = (sgot->output_section->vma - + sgot->output_offset - + off); - outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); - outrel.r_addend = relocation; - bfd_elf64_swap_reloca_out (output_bfd, &outrel, - (((Elf64_External_Rela *) - srelgot->contents) - + srelgot->reloc_count)); - ++srelgot->reloc_count; - } - - local_got_offsets[r_symndx] |= 1; - } - - relocation = sgot->output_offset + off; - } - - break; - case R_X86_64_GOTPCREL: /* Use global offset table as symbol value. */ - BFD_ASSERT (sgot != NULL); + if (h != NULL) { bfd_vma off = h->got.offset; @@ -1437,7 +1355,10 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, h->got.offset |= 1; } } - relocation = sgot->output_offset + off; + if (r_type == R_X86_64_GOTPCREL) + relocation = sgot->output_section->vma + sgot->output_offset + off; + else + relocation = sgot->output_offset + off; } else { @@ -1482,7 +1403,10 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section, local_got_offsets[r_symndx] |= 1; } - relocation = sgot->output_section->vma + off; + if (r_type == R_X86_64_GOTPCREL) + relocation = sgot->output_section->vma + sgot->output_offset + off; + else + relocation = sgot->output_offset + off; } break; @@ -1769,6 +1693,52 @@ elf64_x86_64_finish_dynamic_symbol (output_bfd, info, h, sym) } } + if (h->got.offset != (bfd_vma) -1) + { + asection *sgot; + asection *srela; + Elf_Internal_Rela rela; + + /* This symbol has an entry in the global offset table. Set it + up. */ + + sgot = bfd_get_section_by_name (dynobj, ".got"); + srela = bfd_get_section_by_name (dynobj, ".rela.got"); + BFD_ASSERT (sgot != NULL && srela != NULL); + + rela.r_offset = (sgot->output_section->vma + + sgot->output_offset + + (h->got.offset &~ 1)); + + /* If this is a static link, or it is a -Bsymbolic link and the + symbol is defined locally or was forced to be local because + of a version file, 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 (! elf_hash_table (info)->dynamic_sections_created + || (info->shared + && (info->symbolic || h->dynindx == -1) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))) + { + rela.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE); + rela.r_addend = (h->root.u.def.value + + h->root.u.def.section->output_section->vma + + h->root.u.def.section->output_offset); + } + else + { + BFD_ASSERT((h->got.offset & 1) == 0); + bfd_put_64 (output_bfd, (bfd_vma) 0, sgot->contents + h->got.offset); + rela.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_GLOB_DAT); + rela.r_addend = 0; + } + + bfd_elf64_swap_reloca_out (output_bfd, &rela, + ((Elf64_External_Rela *) srela->contents + + srela->reloc_count)); + ++srela->reloc_count; + } + if ((h->elf_link_hash_flags & ELF_LINK_HASH_NEEDS_COPY) != 0) { asection *s; @@ -1840,7 +1810,7 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) switch (dyn.d_tag) { default: - break; + continue; case DT_PLTGOT: name = ".got"; @@ -1878,7 +1848,6 @@ elf64_x86_64_finish_dynamic_sections (output_bfd, info) (s->_cooked_size != 0 ? s->_cooked_size : s->_raw_size); break; } - bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon); }