(elf64_x86_64_relocate_section): Fix creation of dynamic symbols.
authorAndreas Jaeger <aj@suse.de>
Tue, 19 Jun 2001 13:30:40 +0000 (13:30 +0000)
committerAndreas Jaeger <aj@suse.de>
Tue, 19 Jun 2001 13:30:40 +0000 (13:30 +0000)
bfd/ChangeLog
bfd/elf64-x86-64.c

index 9c3f8a1..2739ca4 100644 (file)
@@ -1,3 +1,8 @@
+2001-06-19  Andreas Jaeger  <aj@suse.de>
+
+       * elf64-x86-64.c (elf64_x86_64_relocate_section): Fix creation of
+       dynamic symbols.
+
 2001-06-18  Hans-Peter Nilsson  <hp@axis.com>
 
        * elflink.h (struct elf_assign_sym_version_info): Remove member
index 079c968..57d4005 100644 (file)
@@ -1439,13 +1439,16 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
                        + h->plt.offset);
          break;
 
+       case R_X86_64_PC8:
+       case R_X86_64_PC16:
+       case R_X86_64_PC32:
+         if (h == NULL)
+           break;
+         /* Fall through.  */
        case R_X86_64_8:
        case R_X86_64_16:
        case R_X86_64_32:
        case R_X86_64_64:
-       case R_X86_64_PC8:
-       case R_X86_64_PC16:
-       case R_X86_64_PC32:
          /* FIXME: The ABI says the linker should make sure the value is
             the same when it's zeroextended to 64 bit.  */
          if (info->shared
@@ -1453,11 +1456,10 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
              && ((r_type != R_X86_64_PC8
                   && r_type != R_X86_64_PC16
                   && r_type != R_X86_64_PC32)
-                 || (h != NULL
-                     && h->dynindx != -1
-                     && (! info->symbolic
-                         || (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+                 || (! info->symbolic
+                     || (h->elf_link_hash_flags
+                         & ELF_LINK_HASH_DEF_REGULAR) == 0)))
+
            {
              Elf_Internal_Rela outrel;
              boolean skip, relocate;
@@ -1512,23 +1514,21 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
                  memset (&outrel, 0, sizeof outrel);
                  relocate = false;
                }
-             else if ((r_type == R_X86_64_PC8)
-                      || (r_type == R_X86_64_PC16)
-                      || (r_type == R_X86_64_PC32))
+             /* h->dynindx may be -1 if this symbol was marked to
+                become local.  */
+             else if (h != NULL
+                      && ((! info->symbolic && h->dynindx != -1)
+                          || (h->elf_link_hash_flags
+                              & ELF_LINK_HASH_DEF_REGULAR) == 0))
                {
-                 BFD_ASSERT (h != NULL && h->dynindx != -1);
+                 BFD_ASSERT (h->dynindx != -1);
                  relocate = false;
                  outrel.r_info = ELF64_R_INFO (h->dynindx, r_type);
                  outrel.r_addend = relocation + rela->r_addend;
                }
              else
                {
-                 /* h->dynindx may be -1 if this symbol was marked to
-                    become local.  */
-                 if (h == NULL
-                     || ((info->symbolic || h->dynindx == -1)
-                         && (h->elf_link_hash_flags
-                             & ELF_LINK_HASH_DEF_REGULAR) != 0))
+                 if (r_type == R_X86_64_64)
                    {
                      relocate = true;
                      outrel.r_info = ELF64_R_INFO (0, R_X86_64_RELATIVE);
@@ -1536,11 +1536,38 @@ elf64_x86_64_relocate_section (output_bfd, info, input_bfd, input_section,
                    }
                  else
                    {
-                     BFD_ASSERT (h->dynindx != -1);
-                     relocate = false;
-                     outrel.r_info = ELF64_R_INFO (h->dynindx, R_X86_64_32);
-                     outrel.r_addend = relocation + rela->r_addend;
-                   }
+                     long indx;
+
+                     if (h == NULL)
+                       sec = local_sections[r_symndx];
+                     else
+                       {
+                         BFD_ASSERT (h->root.type == bfd_link_hash_defined
+                                     || (h->root.type
+                                         == bfd_link_hash_defweak));
+                         sec = h->root.u.def.section;
+                       }
+                     if (sec != NULL && bfd_is_abs_section (sec))
+                       indx = 0;
+                     else if (sec == NULL || sec->owner == NULL)
+                       {
+                         bfd_set_error (bfd_error_bad_value);
+                         return false;
+                       }
+                     else
+                       {
+                         asection *osec;
+
+                         osec = sec->output_section;
+                         indx = elf_section_data (osec)->dynindx;
+                         BFD_ASSERT (indx > 0);
+                       }
+
+                     relocate = false;
+                     outrel.r_info = ELF64_R_INFO (indx, r_type);
+                     outrel.r_addend = relocation + rela->r_addend;
+                   }
+
                }
 
              bfd_elf64_swap_reloca_out (output_bfd, &outrel,