or1k: Fix incorrect value in PLT GOT entries, causing infinite loop
[external/binutils.git] / bfd / elf64-hppa.c
index aa6284a..7781158 100644 (file)
@@ -1,5 +1,5 @@
 /* Support for HPPA 64-bit ELF
-   Copyright (C) 1999-2017 Free Software Foundation, Inc.
+   Copyright (C) 1999-2019 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
@@ -265,7 +265,7 @@ hppa64_link_hash_newfunc (struct bfd_hash_entry *entry,
       entry = bfd_hash_allocate (table,
                                 sizeof (struct elf64_hppa_link_hash_entry));
       if (entry == NULL)
-        return entry;
+       return entry;
     }
 
   /* Call the allocation method of the superclass.  */
@@ -349,9 +349,9 @@ elf64_hppa_object_p (bfd *abfd)
       return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 11);
     case EFA_PARISC_2_0:
       if (i_ehdrp->e_ident[EI_CLASS] == ELFCLASS64)
-        return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
+       return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
       else
-        return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
+       return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 20);
     case EFA_PARISC_2_0 | EF_PARISC_WIDE:
       return bfd_default_set_arch_mach (abfd, bfd_arch_hppa, 25);
     }
@@ -441,8 +441,8 @@ count_dyn_reloc (bfd *abfd,
                 struct elf64_hppa_link_hash_entry *hh,
                 int type,
                 asection *sec,
-                int sec_symndx,
-                bfd_vma offset,
+                int sec_symndx,
+                bfd_vma offset,
                 bfd_vma addend)
 {
   struct elf64_hppa_dyn_reloc_entry *rent;
@@ -1635,9 +1635,9 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
              *local_dlt = sec->size;
              sec->size += DLT_ENTRY_SIZE;
              if (bfd_link_pic (info))
-               {
+               {
                  srel->size += sizeof (Elf64_External_Rela);
-               }
+               }
            }
          else
            *local_dlt = (bfd_vma) -1;
@@ -1711,7 +1711,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
     {
       data.ofs = hppa_info->plt_sec->size;
       elf_link_hash_traverse (&hppa_info->root,
-                             allocate_global_data_plt, &data);
+                             allocate_global_data_plt, &data);
       hppa_info->plt_sec->size = data.ofs;
     }
 
@@ -2011,7 +2011,7 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
         in the output_offset of the PLT section.  */
 
       bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset);
-      value = _bfd_get_gp_value (splt->output_section->owner);
+      value = _bfd_get_gp_value (info->output_bfd);
       bfd_put_64 (splt->owner, value, splt->contents + hh->plt_offset + 0x8);
 
       /* Create a dynamic IPLT relocation for this entry.
@@ -2027,7 +2027,7 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
 
       loc = spltrel->contents;
       loc += spltrel->reloc_count++ * sizeof (Elf64_External_Rela);
-      bfd_elf64_swap_reloca_out (splt->output_section->owner, &rel, loc);
+      bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
     }
 
   /* Initialize an external call stub entry if requested.  */
@@ -2078,8 +2078,8 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
        {
          _bfd_error_handler
            /* xgettext:c-format */
-           (_("stub entry for %s cannot load .plt, dp offset = %Ld"),
-            hh->eh.root.root.string, value);
+           (_("stub entry for %s cannot load .plt, dp offset = %" PRId64),
+            hh->eh.root.root.string, (int64_t) value);
          return FALSE;
        }
 
@@ -2143,7 +2143,7 @@ elf64_hppa_finalize_opd (struct elf_link_hash_entry *eh, void *data)
       bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 16);
 
       /* The last word is our local __gp value.  */
-      value = _bfd_get_gp_value (sopd->output_section->owner);
+      value = _bfd_get_gp_value (info->output_bfd);
       bfd_put_64 (sopd->owner, value, sopd->contents + hh->opd_offset + 24);
     }
 
@@ -2220,7 +2220,7 @@ elf64_hppa_finalize_opd (struct elf_link_hash_entry *eh, void *data)
 
       loc = sopdrel->contents;
       loc += sopdrel->reloc_count++ * sizeof (Elf64_External_Rela);
-      bfd_elf64_swap_reloca_out (sopd->output_section->owner, &rel, loc);
+      bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
     }
   return TRUE;
 }
@@ -2315,7 +2315,7 @@ elf64_hppa_finalize_dlt (struct elf_link_hash_entry *eh, void *data)
 
       loc = sdltrel->contents;
       loc += sdltrel->reloc_count++ * sizeof (Elf64_External_Rela);
-      bfd_elf64_swap_reloca_out (sdlt->output_section->owner, &rel, loc);
+      bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
     }
   return TRUE;
 }
@@ -2431,8 +2431,7 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
          loc = hppa_info->other_rel_sec->contents;
          loc += (hppa_info->other_rel_sec->reloc_count++
                  * sizeof (Elf64_External_Rela));
-         bfd_elf64_swap_reloca_out (hppa_info->other_rel_sec->output_section->owner,
-                                    &rel, loc);
+         bfd_elf64_swap_reloca_out (info->output_bfd, &rel, loc);
        }
     }
 
@@ -3283,10 +3282,10 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
          {
            _bfd_error_handler
              /* xgettext:c-format */
-             (_("%B(%A+%#Lx): cannot reach %s"),
+             (_("%pB(%pA+%#" PRIx64 "): cannot reach %s"),
              input_bfd,
              input_section,
-             offset,
+             (uint64_t) offset,
              eh ? eh->root.root.string : "unknown");
            bfd_set_error (bfd_error_bad_value);
            return bfd_reloc_overflow;
@@ -3347,8 +3346,8 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
          {
            bfd_vma *local_opd_offsets, *local_dlt_offsets;
 
-            if (local_offsets == NULL)
-              abort ();
+           if (local_offsets == NULL)
+             abort ();
 
            /* Now do .opd creation if needed.  */
            if (r_type == R_PARISC_LTOFF_FPTR14R
@@ -3381,8 +3380,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
                                (hppa_info->opd_sec->contents + off + 16));
 
                    /* The last word is our local __gp value.  */
-                   value = _bfd_get_gp_value
-                             (hppa_info->opd_sec->output_section->owner);
+                   value = _bfd_get_gp_value (info->output_bfd);
                    bfd_put_64 (hppa_info->opd_sec->owner, value,
                                (hppa_info->opd_sec->contents + off + 24));
                  }
@@ -3556,33 +3554,12 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 
     case R_PARISC_LTOFF_FPTR32:
       {
-       /* We may still need to create the FPTR itself if it was for
-          a local symbol.  */
-       if (hh == NULL)
-         {
-           /* The first two words of an .opd entry are zero.  */
-           memset (hppa_info->opd_sec->contents + hh->opd_offset, 0, 16);
-
-           /* The next word is the address of the function.  */
-           bfd_put_64 (hppa_info->opd_sec->owner, value + addend,
-                       (hppa_info->opd_sec->contents
-                        + hh->opd_offset + 16));
-
-           /* The last word is our local __gp value.  */
-           value = _bfd_get_gp_value
-                     (hppa_info->opd_sec->output_section->owner);
-           bfd_put_64 (hppa_info->opd_sec->owner, value,
-                       hppa_info->opd_sec->contents + hh->opd_offset + 24);
-
-           /* The DLT value is the address of the .opd entry.  */
-           value = (hh->opd_offset
-                    + hppa_info->opd_sec->output_offset
-                    + hppa_info->opd_sec->output_section->vma);
-
-           bfd_put_64 (hppa_info->dlt_sec->owner,
-                       value,
-                       hppa_info->dlt_sec->contents + hh->dlt_offset);
-         }
+       /* FIXME: There used to be code here to create the FPTR itself if
+          the relocation was against a local symbol.  But the code could
+          never have worked.  If the assert below is ever triggered then
+          the code will need to be reinstated and fixed so that it does
+          what is needed.  */
+       BFD_ASSERT (hh != NULL);
 
        /* We want the value of the DLT offset for this symbol, not
           the symbol's actual address.  Note that __gp may not point
@@ -3612,8 +3589,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
                         + hh->opd_offset + 16));
 
            /* The last word is our local __gp value.  */
-           value = _bfd_get_gp_value
-                     (hppa_info->opd_sec->output_section->owner);
+           value = _bfd_get_gp_value (info->output_bfd);
            bfd_put_64 (hppa_info->opd_sec->owner, value,
                        hppa_info->opd_sec->contents + hh->opd_offset + 24);
 
@@ -3716,8 +3692,8 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
          {
            bfd_vma *local_opd_offsets;
 
-            if (local_offsets == NULL)
-              abort ();
+           if (local_offsets == NULL)
+             abort ();
 
            local_opd_offsets = local_offsets + 2 * symtab_hdr->sh_info;
            off = local_opd_offsets[r_symndx];
@@ -3727,7 +3703,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
            if ((off & 1) != 0)
              {
                BFD_ASSERT (off != (bfd_vma) -1);
-               off &= ~1;
+               off &= ~1;
              }
            else
              {
@@ -3739,8 +3715,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
                            (hppa_info->opd_sec->contents + off + 16));
 
                /* The last word is our local __gp value.  */
-               value = _bfd_get_gp_value
-                         (hppa_info->opd_sec->output_section->owner);
+               value = _bfd_get_gp_value (info->output_bfd);
                bfd_put_64 (hppa_info->opd_sec->owner, value,
                            hppa_info->opd_sec->contents + off + 24);
              }
@@ -3916,19 +3891,19 @@ elf64_hppa_relocate_section (bfd *output_bfd,
                                                    rel->r_offset, err);
            }
 
-          if (!bfd_link_relocatable (info)
-              && relocation == 0
-              && eh->root.type != bfd_link_hash_defined
-              && eh->root.type != bfd_link_hash_defweak
-              && eh->root.type != bfd_link_hash_undefweak)
-            {
-              if (info->unresolved_syms_in_objects == RM_IGNORE
-                  && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
-                  && eh->type == STT_PARISC_MILLI)
+         if (!bfd_link_relocatable (info)
+             && relocation == 0
+             && eh->root.type != bfd_link_hash_defined
+             && eh->root.type != bfd_link_hash_defweak
+             && eh->root.type != bfd_link_hash_undefweak)
+           {
+             if (info->unresolved_syms_in_objects == RM_IGNORE
+                 && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT
+                 && eh->type == STT_PARISC_MILLI)
                (*info->callbacks->undefined_symbol)
                  (info, eh_name (eh), input_bfd,
                   input_section, rel->r_offset, FALSE);
-            }
+           }
        }
 
       if (sym_sec != NULL && discarded_section (sym_sec))
@@ -3979,14 +3954,14 @@ elf64_hppa_relocate_section (bfd *output_bfd,
 
 static const struct bfd_elf_special_section elf64_hppa_special_sections[] =
 {
-  { STRING_COMMA_LEN (".fini"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-  { STRING_COMMA_LEN (".init"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
-  { STRING_COMMA_LEN (".plt"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
-  { STRING_COMMA_LEN (".dlt"),   0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+  { STRING_COMMA_LEN (".tbss"),         0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
+  { STRING_COMMA_LEN (".fini"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".init"),         0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE },
+  { STRING_COMMA_LEN (".plt"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+  { STRING_COMMA_LEN (".dlt"),  0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
   { STRING_COMMA_LEN (".sdata"), 0, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
-  { STRING_COMMA_LEN (".sbss"),  0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
-  { STRING_COMMA_LEN (".tbss"),  0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_HP_TLS },
-  { NULL,                    0,  0, 0,            0 }
+  { STRING_COMMA_LEN (".sbss"),         0, SHT_NOBITS, SHF_ALLOC + SHF_WRITE + SHF_PARISC_SHORT },
+  { NULL,                   0,  0, 0,            0 }
 };
 
 /* The hash bucket size is the standard one, namely 4.  */
@@ -4052,8 +4027,8 @@ const struct elf_size_info hppa64_elf_size_info =
                                        elf64_hppa_create_dynamic_sections
 #define elf_backend_post_process_headers       elf64_hppa_post_process_headers
 
-#define elf_backend_omit_section_dynsym \
-  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
+
 #define elf_backend_adjust_dynamic_symbol \
                                        elf64_hppa_adjust_dynamic_symbol
 
@@ -4113,5 +4088,7 @@ const struct elf_size_info hppa64_elf_size_info =
 #define ELF_OSABI                      ELFOSABI_GNU
 #undef elf64_bed
 #define elf64_bed                      elf64_hppa_linux_bed
+#undef elf_backend_special_sections
+#define elf_backend_special_sections   (elf64_hppa_special_sections + 1)
 
 #include "elf64-target.h"