* elf64-x86-64.c (elf64_x86_64_finish_dynamic_sections): Only swap
authorAndreas Jaeger <aj@suse.de>
Sun, 29 Apr 2001 13:42:45 +0000 (13:42 +0000)
committerAndreas Jaeger <aj@suse.de>
Sun, 29 Apr 2001 13:42:45 +0000 (13:42 +0000)
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.

bfd/ChangeLog
bfd/elf64-x86-64.c

index 4e3860d56921ab37a9f013e1fe1a1d615713aa39..f9cc5e38d807b510a5e879f6cce8faf6c136209c 100644 (file)
@@ -1,3 +1,12 @@
+2001-04-27  Andreas Jaeger  <aj@suse.de>
+
+       * 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 <sean@mcneil.com>
 
        * config.bfd: Add arm-vxworks target.
        (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.
index 912f666bfba62c874e87b7349bffb63e4d9777da..f23e06cdb13e4d3e24731c16401b2756f61b25f8 100644 (file)
@@ -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);
        }