gdb: add target_ops::supports_displaced_step
[deliverable/binutils-gdb.git] / bfd / elf64-hppa.c
index 11289b13916d06c8e70654cb33f70f5e0148b32d..7fc2dc0e0c1384babf3b7eee1c56c1a735d40dbc 100644 (file)
@@ -1,6 +1,5 @@
 /* Support for HPPA 64-bit ELF
-   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
-   2010  Free Software Foundation, Inc.
+   Copyright (C) 1999-2020 Free Software Foundation, Inc.
 
    This file is part of BFD, the Binary File Descriptor library.
 
    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
    MA 02110-1301, USA.  */
 
-#include "alloca-conf.h"
 #include "sysdep.h"
+#include "alloca-conf.h"
 #include "bfd.h"
 #include "libbfd.h"
 #include "elf-bfd.h"
 #include "elf/hppa.h"
 #include "libhppa.h"
 #include "elf64-hppa.h"
-
+#include "libiberty.h"
 
 #define ARCH_SIZE             64
 
@@ -170,9 +169,6 @@ static struct bfd_link_hash_table *elf64_hppa_hash_table_create
 static bfd_boolean elf64_hppa_object_p
   (bfd *);
 
-static void elf64_hppa_post_process_headers
-  (bfd *, struct bfd_link_info *);
-
 static bfd_boolean elf64_hppa_create_dynamic_sections
   (bfd *, struct bfd_link_info *);
 
@@ -193,9 +189,6 @@ static bfd_boolean elf64_hppa_finish_dynamic_symbol
   (bfd *, struct bfd_link_info *,
    struct elf_link_hash_entry *, Elf_Internal_Sym *);
 
-static enum elf_reloc_type_class elf64_hppa_reloc_type_class
-  (const Elf_Internal_Rela *);
-
 static bfd_boolean elf64_hppa_finish_dynamic_sections
   (bfd *, struct bfd_link_info *);
 
@@ -269,7 +262,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.  */
@@ -296,9 +289,9 @@ static struct bfd_link_hash_table*
 elf64_hppa_hash_table_create (bfd *abfd)
 {
   struct elf64_hppa_link_hash_table *htab;
-  bfd_size_type amt = sizeof (*htab);
+  size_t amt = sizeof (*htab);
 
-  htab = bfd_zalloc (abfd, amt);
+  htab = bfd_zmalloc (amt);
   if (htab == NULL)
     return NULL;
 
@@ -307,7 +300,7 @@ elf64_hppa_hash_table_create (bfd *abfd)
                                      sizeof (struct elf64_hppa_link_hash_entry),
                                      HPPA64_ELF_DATA))
     {
-      bfd_release (abfd, htab);
+      free (htab);
       return NULL;
     }
 
@@ -329,9 +322,9 @@ elf64_hppa_object_p (bfd *abfd)
   i_ehdrp = elf_elfheader (abfd);
   if (strcmp (bfd_get_target (abfd), "elf64-hppa-linux") == 0)
     {
-      /* GCC on hppa-linux produces binaries with OSABI=Linux,
+      /* GCC on hppa-linux produces binaries with OSABI=GNU,
         but the kernel produces corefiles with OSABI=SysV.  */
-      if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_LINUX
+      if (i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_GNU
          && i_ehdrp->e_ident[EI_OSABI] != ELFOSABI_NONE) /* aka SYSV */
        return FALSE;
     }
@@ -353,9 +346,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);
     }
@@ -390,7 +383,9 @@ elf64_hppa_section_from_shdr (bfd *abfd,
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
     return FALSE;
 
-  return TRUE;
+  return ((hdr->sh_flags & SHF_PARISC_SHORT) == 0
+         || bfd_set_section_flags (hdr->bfd_section,
+                                   hdr->bfd_section->flags | SEC_SMALL_DATA));
 }
 
 /* SEC is a section containing relocs for an input BFD when linking; return
@@ -411,29 +406,22 @@ get_reloc_section (bfd *abfd,
   if (srel_name == NULL)
     return FALSE;
 
-  BFD_ASSERT ((CONST_STRNEQ (srel_name, ".rela")
-              && strcmp (bfd_get_section_name (abfd, sec),
-                         srel_name + 5) == 0)
-             || (CONST_STRNEQ (srel_name, ".rel")
-                 && strcmp (bfd_get_section_name (abfd, sec),
-                            srel_name + 4) == 0));
-
   dynobj = hppa_info->root.dynobj;
   if (!dynobj)
     hppa_info->root.dynobj = dynobj = abfd;
 
-  srel = bfd_get_section_by_name (dynobj, srel_name);
+  srel = bfd_get_linker_section (dynobj, srel_name);
   if (srel == NULL)
     {
-      srel = bfd_make_section_with_flags (dynobj, srel_name,
-                                         (SEC_ALLOC
-                                          | SEC_LOAD
-                                          | SEC_HAS_CONTENTS
-                                          | SEC_IN_MEMORY
-                                          | SEC_LINKER_CREATED
-                                          | SEC_READONLY));
+      srel = bfd_make_section_anyway_with_flags (dynobj, srel_name,
+                                                (SEC_ALLOC
+                                                 | SEC_LOAD
+                                                 | SEC_HAS_CONTENTS
+                                                 | SEC_IN_MEMORY
+                                                 | SEC_LINKER_CREATED
+                                                 | SEC_READONLY));
       if (srel == NULL
-         || !bfd_set_section_alignment (dynobj, srel, 3))
+         || !bfd_set_section_alignment (srel, 3))
        return FALSE;
     }
 
@@ -452,8 +440,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;
@@ -482,7 +470,7 @@ hppa64_elf_local_refcounts (bfd *abfd)
 {
   Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   bfd_signed_vma *local_refcounts;
-                  
+
   local_refcounts = elf_local_got_refcounts (abfd);
   if (local_refcounts == NULL)
     {
@@ -514,7 +502,7 @@ elf64_hppa_check_relocs (bfd *abfd,
   const Elf_Internal_Rela *rel;
   unsigned int sec_symndx;
 
-  if (info->relocatable)
+  if (bfd_link_relocatable (info))
     return TRUE;
 
   /* If this is the first dynamic object found in the link, create
@@ -533,7 +521,7 @@ elf64_hppa_check_relocs (bfd *abfd,
   /* If necessary, build a new table holding section symbols indices
      for this BFD.  */
 
-  if (info->shared && hppa_info->section_syms_bfd != abfd)
+  if (bfd_link_pic (info) && hppa_info->section_syms_bfd != abfd)
     {
       unsigned long i;
       unsigned int highest_shndx;
@@ -546,8 +534,7 @@ elf64_hppa_check_relocs (bfd *abfd,
 
         ?!? Note we leak the last section_syms array.  Presumably we
         could free it in one of the later routines in this file.  */
-      if (hppa_info->section_syms)
-       free (hppa_info->section_syms);
+      free (hppa_info->section_syms);
 
       /* Read this BFD's local symbols.  */
       if (symtab_hdr->sh_info != 0)
@@ -607,7 +594,7 @@ elf64_hppa_check_relocs (bfd *abfd,
      relocations when building shared libraries.  When not building shared
      libraries this value is never really used, but assign it to zero to
      prevent out of bounds memory accesses in other routines.  */
-  if (info->shared)
+  if (bfd_link_pic (info))
     {
       sec_symndx = _bfd_elf_section_from_bfd_section (abfd, sec);
 
@@ -653,6 +640,8 @@ elf64_hppa_check_relocs (bfd *abfd,
                 || hh->eh.root.type == bfd_link_hash_warning)
            hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
 
+         /* PR15323, ref flags aren't set for references in the same
+            object.  */
          hh->eh.ref_regular = 1;
        }
       else
@@ -663,7 +652,7 @@ elf64_hppa_check_relocs (bfd *abfd,
         have yet been processed.  Do something with what we know, as
         this may help reduce memory usage and processing time later.  */
       maybe_dynamic = FALSE;
-      if (hh && ((info->shared
+      if (hh && ((bfd_link_pic (info)
                 && (!info->symbolic
                     || info->unresolved_syms_in_shared_libs == RM_IGNORE))
                || !hh->eh.def_regular
@@ -738,7 +727,7 @@ elf64_hppa_check_relocs (bfd *abfd,
          break;
 
        case R_PARISC_DIR64:
-         if (info->shared || maybe_dynamic)
+         if (bfd_link_pic (info) || maybe_dynamic)
            need_entry = (NEED_DYNREL);
          dynrel_type = R_PARISC_DIR64;
          break;
@@ -755,7 +744,7 @@ elf64_hppa_check_relocs (bfd *abfd,
        case R_PARISC_LTOFF_FPTR16F:
        case R_PARISC_LTOFF_FPTR16WF:
        case R_PARISC_LTOFF_FPTR16DF:
-         if (info->shared || maybe_dynamic)
+         if (bfd_link_pic (info) || maybe_dynamic)
            need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
          else
            need_entry = (NEED_DLT | NEED_OPD | NEED_PLT);
@@ -764,7 +753,7 @@ elf64_hppa_check_relocs (bfd *abfd,
 
        /* This is a simple OPD entry.  */
        case R_PARISC_FPTR64:
-         if (info->shared || maybe_dynamic)
+         if (bfd_link_pic (info) || maybe_dynamic)
            need_entry = (NEED_OPD | NEED_PLT | NEED_DYNREL);
          else
            need_entry = (NEED_OPD | NEED_PLT);
@@ -802,7 +791,7 @@ elf64_hppa_check_relocs (bfd *abfd,
          else
            {
              bfd_signed_vma *local_dlt_refcounts;
-                  
+
              /* This is a DLT entry for a local symbol.  */
              local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
              if (local_dlt_refcounts == NULL)
@@ -827,7 +816,7 @@ elf64_hppa_check_relocs (bfd *abfd,
            {
              bfd_signed_vma *local_dlt_refcounts;
              bfd_signed_vma *local_plt_refcounts;
-                  
+
              /* This is a PLT entry for a local symbol.  */
              local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
              if (local_dlt_refcounts == NULL)
@@ -861,7 +850,7 @@ elf64_hppa_check_relocs (bfd *abfd,
            {
              bfd_signed_vma *local_dlt_refcounts;
              bfd_signed_vma *local_opd_refcounts;
-                  
+
              /* This is a OPD for a local symbol.  */
              local_dlt_refcounts = hppa64_elf_local_refcounts (abfd);
              if (local_dlt_refcounts == NULL)
@@ -890,7 +879,7 @@ elf64_hppa_check_relocs (bfd *abfd,
             a dynamic R_PARISC_FPTR64 relocation, then make sure the
             section symbol for this section ends up in the dynamic
             symbol table.  */
-         if (info->shared && dynrel_type == R_PARISC_FPTR64
+         if (bfd_link_pic (info) && dynrel_type == R_PARISC_FPTR64
              && ! (bfd_elf_link_record_local_dynamic_symbol
                    (info, abfd, sec_symndx)))
            return FALSE;
@@ -944,9 +933,6 @@ elf64_hppa_mark_exported_functions (struct elf_link_hash_entry *eh, void *data)
   if (hppa_info == NULL)
     return FALSE;
 
-  if (eh->root.type == bfd_link_hash_warning)
-    eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
-
   if (eh
       && (eh->root.type == bfd_link_hash_defined
          || eh->root.type == bfd_link_hash_defweak)
@@ -977,7 +963,7 @@ allocate_global_data_dlt (struct elf_link_hash_entry *eh, void *data)
 
   if (hh->want_dlt)
     {
-      if (x->info->shared)
+      if (bfd_link_pic (x->info))
        {
          /* Possibly add the symbol to the local dynamic symbol
             table since we might need to create a dynamic relocation
@@ -1063,10 +1049,6 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
 
   if (hh && hh->want_opd)
     {
-      while (hh->eh.root.type == bfd_link_hash_indirect
-            || hh->eh.root.type == bfd_link_hash_warning)
-       hh = hppa_elf_hash_entry (hh->eh.root.u.i.link);
-
       /* We never need an opd entry for a symbol which is not
         defined by this output file.  */
       if (hh && (hh->eh.root.type == bfd_link_hash_undefined
@@ -1077,7 +1059,7 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
       /* If we are creating a shared library, took the address of a local
         function or might export this function from this object file, then
         we have to create an opd descriptor.  */
-      else if (x->info->shared
+      else if (bfd_link_pic (x->info)
               || hh == NULL
               || (hh->eh.dynindx == -1 && hh->eh.type != STT_PARISC_MILLI)
               || (hh->eh.root.type == bfd_link_hash_defined
@@ -1087,7 +1069,7 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
             create a runtime relocation for the symbol to properly
             initialize the .opd entry.  Make sure the symbol gets
             added to the dynamic symbol table.  */
-         if (x->info->shared
+         if (bfd_link_pic (x->info)
              && (hh == NULL || (hh->eh.dynindx == -1)))
            {
              bfd *owner;
@@ -1104,25 +1086,23 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
             in dynamic relocs.  But name munging does make the result
             much easier to debug.  ie, the EPLT reloc will reference
             a symbol like .foobar, instead of .text + offset.  */
-         if (x->info->shared && eh)
+         if (bfd_link_pic (x->info) && eh)
            {
              char *new_name;
              struct elf_link_hash_entry *nh;
 
-             new_name = alloca (strlen (eh->root.root.string) + 2);
-             new_name[0] = '.';
-             strcpy (new_name + 1, eh->root.root.string);
+             new_name = concat (".", eh->root.root.string, NULL);
 
              nh = elf_link_hash_lookup (elf_hash_table (x->info),
                                         new_name, TRUE, TRUE, TRUE);
 
+             free (new_name);
              nh->root.type = eh->root.type;
              nh->root.u.def.value = eh->root.u.def.value;
              nh->root.u.def.section = eh->root.u.def.section;
 
              if (! bfd_elf_link_record_dynamic_symbol (x->info, nh))
                return FALSE;
-
             }
          hh->opd_offset = x->ofs;
          x->ofs += OPD_ENTRY_SIZE;
@@ -1138,16 +1118,18 @@ allocate_global_data_opd (struct elf_link_hash_entry *eh, void *data)
 /* HP requires the EI_OSABI field to be filled in.  The assignment to
    EI_ABIVERSION may not be strictly necessary.  */
 
-static void
-elf64_hppa_post_process_headers (bfd *abfd,
-                        struct bfd_link_info *link_info ATTRIBUTE_UNUSED)
+static bfd_boolean
+elf64_hppa_init_file_header (bfd *abfd, struct bfd_link_info *info)
 {
-  Elf_Internal_Ehdr * i_ehdrp;
+  Elf_Internal_Ehdr *i_ehdrp;
+
+  if (!_bfd_elf_init_file_header (abfd, info))
+    return FALSE;
 
   i_ehdrp = elf_elfheader (abfd);
-  
   i_ehdrp->e_ident[EI_OSABI] = get_elf_backend_data (abfd)->elf_osabi;
   i_ehdrp->e_ident[EI_ABIVERSION] = 1;
+  return TRUE;
 }
 
 /* Create function descriptor section (.opd).  This section is called .opd
@@ -1170,14 +1152,14 @@ get_opd (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      opd = bfd_make_section_with_flags (dynobj, ".opd",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      opd = bfd_make_section_anyway_with_flags (dynobj, ".opd",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!opd
-         || !bfd_set_section_alignment (abfd, opd, 3))
+         || !bfd_set_section_alignment (opd, 3))
        {
          BFD_ASSERT (0);
          return FALSE;
@@ -1206,14 +1188,14 @@ get_plt (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      plt = bfd_make_section_with_flags (dynobj, ".plt",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      plt = bfd_make_section_anyway_with_flags (dynobj, ".plt",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!plt
-         || !bfd_set_section_alignment (abfd, plt, 3))
+         || !bfd_set_section_alignment (plt, 3))
        {
          BFD_ASSERT (0);
          return FALSE;
@@ -1242,14 +1224,14 @@ get_dlt (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      dlt = bfd_make_section_with_flags (dynobj, ".dlt",
-                                        (SEC_ALLOC
-                                         | SEC_LOAD
-                                         | SEC_HAS_CONTENTS
-                                         | SEC_IN_MEMORY
-                                         | SEC_LINKER_CREATED));
+      dlt = bfd_make_section_anyway_with_flags (dynobj, ".dlt",
+                                               (SEC_ALLOC
+                                                | SEC_LOAD
+                                                | SEC_HAS_CONTENTS
+                                                | SEC_IN_MEMORY
+                                                | SEC_LINKER_CREATED));
       if (!dlt
-         || !bfd_set_section_alignment (abfd, dlt, 3))
+         || !bfd_set_section_alignment (dlt, 3))
        {
          BFD_ASSERT (0);
          return FALSE;
@@ -1278,14 +1260,14 @@ get_stub (bfd *abfd,
       if (!dynobj)
        hppa_info->root.dynobj = dynobj = abfd;
 
-      stub = bfd_make_section_with_flags (dynobj, ".stub",
-                                         (SEC_ALLOC | SEC_LOAD
-                                          | SEC_HAS_CONTENTS
-                                          | SEC_IN_MEMORY
-                                          | SEC_READONLY
-                                          | SEC_LINKER_CREATED));
+      stub = bfd_make_section_anyway_with_flags (dynobj, ".stub",
+                                                (SEC_ALLOC | SEC_LOAD
+                                                 | SEC_HAS_CONTENTS
+                                                 | SEC_IN_MEMORY
+                                                 | SEC_READONLY
+                                                 | SEC_LINKER_CREATED));
       if (!stub
-         || !bfd_set_section_alignment (abfd, stub, 3))
+         || !bfd_set_section_alignment (stub, 3))
        {
          BFD_ASSERT (0);
          return FALSE;
@@ -1358,47 +1340,47 @@ elf64_hppa_create_dynamic_sections (bfd *abfd,
   if (! get_opd (abfd, info, hppa_info))
     return FALSE;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.dlt",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.dlt",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
   hppa_info->dlt_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.plt",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.plt",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
   hppa_info->plt_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.data",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.data",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
   hppa_info->other_rel_sec = s;
 
-  s = bfd_make_section_with_flags (abfd, ".rela.opd",
-                                  (SEC_ALLOC | SEC_LOAD
-                                   | SEC_HAS_CONTENTS
-                                   | SEC_IN_MEMORY
-                                   | SEC_READONLY
-                                   | SEC_LINKER_CREATED));
+  s = bfd_make_section_anyway_with_flags (abfd, ".rela.opd",
+                                         (SEC_ALLOC | SEC_LOAD
+                                          | SEC_HAS_CONTENTS
+                                          | SEC_IN_MEMORY
+                                          | SEC_READONLY
+                                          | SEC_LINKER_CREATED));
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, 3))
+      || !bfd_set_section_alignment (s, 3))
     return FALSE;
   hppa_info->opd_rel_sec = s;
 
@@ -1422,7 +1404,7 @@ allocate_dynrel_entries (struct elf_link_hash_entry *eh, void *data)
     return FALSE;
 
   dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, x->info);
-  shared = x->info->shared;
+  shared = bfd_link_pic (x->info);
 
   /* We may need to allocate relocations for a non-dynamic symbol
      when creating a shared library.  */
@@ -1491,12 +1473,12 @@ elf64_hppa_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
   /* If this is a weak symbol, and there is a real definition, the
      processor independent code will have arranged for us to see the
      real definition first, and we can just use the same value.  */
-  if (eh->u.weakdef != NULL)
+  if (eh->is_weakalias)
     {
-      BFD_ASSERT (eh->u.weakdef->root.type == bfd_link_hash_defined
-                 || eh->u.weakdef->root.type == bfd_link_hash_defweak);
-      eh->root.u.def.section = eh->u.weakdef->root.u.def.section;
-      eh->root.u.def.value = eh->u.weakdef->root.u.def.value;
+      struct elf_link_hash_entry *def = weakdef (eh);
+      BFD_ASSERT (def->root.type == bfd_link_hash_defined);
+      eh->root.u.def.section = def->root.u.def.section;
+      eh->root.u.def.value = def->root.u.def.value;
       return TRUE;
     }
 
@@ -1519,19 +1501,15 @@ static bfd_boolean
 elf64_hppa_mark_milli_and_exported_functions (struct elf_link_hash_entry *eh,
                                              void *data)
 {
-  struct elf_link_hash_entry *elf = eh;
-  struct bfd_link_info *info = (struct bfd_link_info *)data;
+  struct bfd_link_info *info = (struct bfd_link_info *) data;
 
-  if (elf->root.type == bfd_link_hash_warning)
-    elf = (struct elf_link_hash_entry *) elf->root.u.i.link;
-
-  if (elf->type == STT_PARISC_MILLI)
+  if (eh->type == STT_PARISC_MILLI)
     {
-      if (elf->dynindx != -1)
+      if (eh->dynindx != -1)
        {
-         elf->dynindx = -1;
+         eh->dynindx = -1;
          _bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
-                                 elf->dynstr_index);
+                                 eh->dynstr_index);
        }
       return TRUE;
     }
@@ -1558,7 +1536,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   if (hppa_info == NULL)
     return FALSE;
 
-  dynobj = elf_hash_table (info)->dynobj;
+  dynobj = hppa_info->root.dynobj;
   BFD_ASSERT (dynobj != NULL);
 
   /* Mark each function this program exports so that we will allocate
@@ -1568,18 +1546,18 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 
      We have to traverse the main linker hash table since we have to
      find functions which may not have been mentioned in any relocs.  */
-  elf_link_hash_traverse (elf_hash_table (info),
-                         (elf_hash_table (info)->dynamic_sections_created
+  elf_link_hash_traverse (&hppa_info->root,
+                         (hppa_info->root.dynamic_sections_created
                           ? elf64_hppa_mark_milli_and_exported_functions
                           : elf64_hppa_mark_exported_functions),
                          info);
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (hppa_info->root.dynamic_sections_created)
     {
       /* Set the contents of the .interp section to the interpreter.  */
-      if (info->executable)
+      if (bfd_link_executable (info) && !info->nointerp)
        {
-         sec = bfd_get_section_by_name (dynobj, ".interp");
+         sec = bfd_get_linker_section (dynobj, ".interp");
          BFD_ASSERT (sec != NULL);
          sec->size = sizeof ELF_DYNAMIC_INTERPRETER;
          sec->contents = (unsigned char *) ELF_DYNAMIC_INTERPRETER;
@@ -1592,14 +1570,14 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
         not actually use these entries.  Reset the size of .rela.dlt,
         which will cause it to get stripped from the output file
         below.  */
-      sec = bfd_get_section_by_name (dynobj, ".rela.dlt");
+      sec = hppa_info->dlt_rel_sec;
       if (sec != NULL)
        sec->size = 0;
     }
 
   /* Set up DLT, PLT and OPD offsets for local syms, and space for local
      dynamic relocs.  */
-  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
+  for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
     {
       bfd_signed_vma *local_dlt;
       bfd_signed_vma *end_local_dlt;
@@ -1656,10 +1634,10 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
            {
              *local_dlt = sec->size;
              sec->size += DLT_ENTRY_SIZE;
-             if (info->shared) 
-               {
+             if (bfd_link_pic (info))
+               {
                  srel->size += sizeof (Elf64_External_Rela);
-               }
+               }
            }
          else
            *local_dlt = (bfd_vma) -1;
@@ -1683,7 +1661,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
                {
                  *local_plt = sec->size;
                  sec->size += PLT_ENTRY_SIZE;
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    srel->size += sizeof (Elf64_External_Rela);
                }
              else
@@ -1709,7 +1687,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
                {
                  *local_opd = sec->size;
                  sec->size += OPD_ENTRY_SIZE;
-                 if (info->shared)
+                 if (bfd_link_pic (info))
                    srel->size += sizeof (Elf64_External_Rela);
                }
              else
@@ -1724,7 +1702,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   if (hppa_info->dlt_sec)
     {
       data.ofs = hppa_info->dlt_sec->size;
-      elf_link_hash_traverse (elf_hash_table (info),
+      elf_link_hash_traverse (&hppa_info->root,
                              allocate_global_data_dlt, &data);
       hppa_info->dlt_sec->size = data.ofs;
     }
@@ -1732,15 +1710,15 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   if (hppa_info->plt_sec)
     {
       data.ofs = hppa_info->plt_sec->size;
-      elf_link_hash_traverse (elf_hash_table (info),
-                             allocate_global_data_plt, &data);
+      elf_link_hash_traverse (&hppa_info->root,
+                             allocate_global_data_plt, &data);
       hppa_info->plt_sec->size = data.ofs;
     }
 
   if (hppa_info->stub_sec)
     {
       data.ofs = 0x0;
-      elf_link_hash_traverse (elf_hash_table (info),
+      elf_link_hash_traverse (&hppa_info->root,
                              allocate_global_data_stub, &data);
       hppa_info->stub_sec->size = data.ofs;
     }
@@ -1749,14 +1727,14 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
   if (hppa_info->opd_sec)
     {
       data.ofs = hppa_info->opd_sec->size;
-      elf_link_hash_traverse (elf_hash_table (info),
+      elf_link_hash_traverse (&hppa_info->root,
                              allocate_global_data_opd, &data);
       hppa_info->opd_sec->size = data.ofs;
     }
 
   /* Now allocate space for dynamic relocations, if necessary.  */
   if (hppa_info->root.dynamic_sections_created)
-    elf_link_hash_traverse (elf_hash_table (info),
+    elf_link_hash_traverse (&hppa_info->root,
                            allocate_dynrel_entries, &data);
 
   /* The sizes of all the sections are set.  Allocate memory for them.  */
@@ -1772,7 +1750,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
 
       /* It's OK to base decisions on the section name, because none
         of the dynobj section names depend upon the input files.  */
-      name = bfd_get_section_name (dynobj, sec);
+      name = bfd_section_name (sec);
 
       if (strcmp (name, ".plt") == 0)
        {
@@ -1805,8 +1783,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
                     entry.  The entries in the .rela.plt section
                     really apply to the .got section, which we
                     created ourselves and so know is not readonly.  */
-                 outname = bfd_get_section_name (output_bfd,
-                                                 sec->output_section);
+                 outname = bfd_section_name (sec->output_section);
                  target = bfd_get_section_by_name (output_bfd, outname + 4);
                  if (target != NULL
                      && (target->flags & SEC_READONLY) != 0
@@ -1857,7 +1834,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
        }
     }
 
-  if (elf_hash_table (info)->dynamic_sections_created)
+  if (hppa_info->root.dynamic_sections_created)
     {
       /* Always create a DT_PLTGOT.  It actually has nothing to do with
         the PLT, it is how we communicate the __gp value of a load
@@ -1874,7 +1851,7 @@ elf64_hppa_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
         must add the entries now so that we get the correct size for
         the .dynamic section.  The DT_DEBUG entry is filled in by the
         dynamic linker and used by the debugger.  */
-      if (! info->shared)
+      if (! bfd_link_pic (info))
        {
          if (!add_dynamic_entry (DT_DEBUG, 0)
              || !add_dynamic_entry (DT_HP_DLD_HOOK, 0)
@@ -2016,7 +1993,7 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
         if we are creating a shared library and the symbol is
         still undefined, we create a dynamic relocation to fill
         in the correct value.  */
-      if (info->shared && eh->root.type == bfd_link_hash_undefined)
+      if (bfd_link_pic (info) && eh->root.type == bfd_link_hash_undefined)
        value = 0;
       else
        value = (eh->root.u.def.value + eh->root.u.def.section->vma);
@@ -2033,7 +2010,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.
@@ -2049,7 +2026,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.  */
@@ -2098,9 +2075,10 @@ elf64_hppa_finish_dynamic_symbol (bfd *output_bfd,
 
       if ((value & 7) || value + max_offset >= 2*max_offset - 8)
        {
-         (*_bfd_error_handler) (_("stub entry for %s cannot load .plt, dp offset = %ld"),
-                                hh->eh.root.root.string,
-                                (long) value);
+         _bfd_error_handler
+           /* xgettext:c-format */
+           (_("stub entry for %s cannot load .plt, dp offset = %" PRId64),
+            hh->eh.root.root.string, (int64_t) value);
          return FALSE;
        }
 
@@ -2164,14 +2142,14 @@ 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);
     }
 
   /* If we are generating a shared library, we must generate EPLT relocations
      for each entry in the .opd, even for static functions (they may have
      had their address taken).  */
-  if (info->shared && hh->want_opd)
+  if (bfd_link_pic (info) && hh->want_opd)
     {
       Elf_Internal_Rela rel;
       bfd_byte *loc;
@@ -2224,17 +2202,16 @@ elf64_hppa_finalize_opd (struct elf_link_hash_entry *eh, void *data)
          char *new_name;
          struct elf_link_hash_entry *nh;
 
-         new_name = alloca (strlen (eh->root.root.string) + 2);
-         new_name[0] = '.';
-         strcpy (new_name + 1, eh->root.root.string);
+         new_name = concat (".", eh->root.root.string, NULL);
 
          nh = elf_link_hash_lookup (elf_hash_table (info),
                                     new_name, TRUE, TRUE, FALSE);
+
          /* All we really want from the new symbol is its dynamic
             symbol index.  */
          if (nh)
            dynindx = nh->dynindx;
+         free (new_name);
        }
 
       rel.r_addend = 0;
@@ -2242,7 +2219,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;
 }
@@ -2270,7 +2247,7 @@ elf64_hppa_finalize_dlt (struct elf_link_hash_entry *eh, void *data)
      address, so there is no need to create a relocation.  Just install
      the proper value into the DLT, note this shortcut can not be
      skipped when building a shared library.  */
-  if (! info->shared && hh && hh->want_dlt)
+  if (! bfd_link_pic (info) && hh && hh->want_dlt)
     {
       bfd_vma value;
 
@@ -2308,7 +2285,7 @@ elf64_hppa_finalize_dlt (struct elf_link_hash_entry *eh, void *data)
   /* Create a relocation for the DLT entry associated with this symbol.
      When building a shared library the symbol does not have to be dynamic.  */
   if (hh->want_dlt
-      && (elf64_hppa_dynamic_symbol_p (eh, info) || info->shared))
+      && (elf64_hppa_dynamic_symbol_p (eh, info) || bfd_link_pic (info)))
     {
       Elf_Internal_Rela rel;
       bfd_byte *loc;
@@ -2337,7 +2314,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;
 }
@@ -2356,7 +2333,7 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 
   dynamic_symbol = elf64_hppa_dynamic_symbol_p (eh, info);
 
-  if (!dynamic_symbol && !info->shared)
+  if (!dynamic_symbol && !bfd_link_pic (info))
     return TRUE;
 
   if (hh->reloc_entries)
@@ -2385,7 +2362,8 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
 
          /* Allocate one iff we are building a shared library, the relocation
             isn't a R_PARISC_FPTR64, or we don't want an opd entry.  */
-         if (!info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+         if (!bfd_link_pic (info)
+             && rent->type == R_PARISC_FPTR64 && hh->want_opd)
            continue;
 
          /* Create a dynamic relocation for this entry.
@@ -2415,7 +2393,8 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
             We use a section symbol recorded by check_relocs as the
             base symbol for the relocation.  The addend is the difference
             between the section symbol and the address of the .opd entry.  */
-         if (info->shared && rent->type == R_PARISC_FPTR64 && hh->want_opd)
+         if (bfd_link_pic (info)
+             && rent->type == R_PARISC_FPTR64 && hh->want_opd)
            {
              bfd_vma value, value2;
 
@@ -2451,8 +2430,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);
        }
     }
 
@@ -2463,7 +2441,9 @@ elf64_hppa_finalize_dynreloc (struct elf_link_hash_entry *eh,
    dynamic linker, before writing them out.  */
 
 static enum elf_reloc_type_class
-elf64_hppa_reloc_type_class (const Elf_Internal_Rela *rela)
+elf64_hppa_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
+                            const asection *rel_sec ATTRIBUTE_UNUSED,
+                            const Elf_Internal_Rela *rela)
 {
   if (ELF64_R_SYM (rela->r_info) == STN_UNDEF)
     return reloc_class_relative;
@@ -2509,7 +2489,7 @@ elf64_hppa_finish_dynamic_sections (bfd *output_bfd,
                          elf64_hppa_finalize_dlt,
                          info);
 
-  sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+  sdyn = bfd_get_linker_section (dynobj, ".dynamic");
 
   if (elf_hash_table (info)->dynamic_sections_created)
     {
@@ -2539,6 +2519,8 @@ elf64_hppa_finish_dynamic_sections (bfd *output_bfd,
                 area at the start of the .data section.  So all we have to
                 to is find the start of the .data section.  */
              s = bfd_get_section_by_name (output_bfd, ".data");
+             if (!s)
+               return FALSE;
              dyn.d_un.d_ptr = s->vma;
              bfd_elf64_swap_dyn_out (output_bfd, &dyn, dyncon);
              break;
@@ -2608,10 +2590,10 @@ elf64_hppa_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
 
       case 760:                /* Linux/hppa */
        /* pr_cursig */
-       elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
+       elf_tdata (abfd)->core->signal = bfd_get_16 (abfd, note->descdata + 12);
 
        /* pr_pid */
-       elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
+       elf_tdata (abfd)->core->lwpid = bfd_get_32 (abfd, note->descdata + 32);
 
        /* pr_reg */
        offset = 112;
@@ -2637,16 +2619,16 @@ elf64_hppa_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
       return FALSE;
 
     case 136:          /* Linux/hppa elf_prpsinfo.  */
-      elf_tdata (abfd)->core_program
+      elf_tdata (abfd)->core->program
        = _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
-      elf_tdata (abfd)->core_command
+      elf_tdata (abfd)->core->command
        = _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
     }
 
   /* Note that for some reason, a spurious space is tacked
      onto the end of the args in some (at least one anyway)
      implementations, so strip it off if it exists.  */
-  command = elf_tdata (abfd)->core_command;
+  command = elf_tdata (abfd)->core->command;
   n = strlen (command);
 
   if (0 < n && command[n - 1] == ' ')
@@ -2681,6 +2663,14 @@ elf64_hppa_additional_program_headers (bfd *abfd,
   return 0;
 }
 
+static bfd_boolean
+elf64_hppa_allow_non_load_phdr (bfd *abfd ATTRIBUTE_UNUSED,
+                               const Elf_Internal_Phdr *phdr ATTRIBUTE_UNUSED,
+                               unsigned int count ATTRIBUTE_UNUSED)
+{
+  return TRUE;
+}
+
 /* Allocate and initialize any program headers required by this
    specific backend.
 
@@ -2695,37 +2685,29 @@ elf64_hppa_additional_program_headers (bfd *abfd,
    existence of a .interp section.  */
 
 static bfd_boolean
-elf64_hppa_modify_segment_map (bfd *abfd,
-                              struct bfd_link_info *info ATTRIBUTE_UNUSED)
+elf64_hppa_modify_segment_map (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf_segment_map *m;
-  asection *s;
 
-  s = bfd_get_section_by_name (abfd, ".interp");
-  if (! s)
+  m = elf_seg_map (abfd);
+  if (info != NULL && !info->user_phdrs && m != NULL && m->p_type != PT_PHDR)
     {
-      for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
-       if (m->p_type == PT_PHDR)
-         break;
+      m = ((struct elf_segment_map *)
+          bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
       if (m == NULL)
-       {
-         m = ((struct elf_segment_map *)
-              bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
-         if (m == NULL)
-           return FALSE;
+       return FALSE;
 
-         m->p_type = PT_PHDR;
-         m->p_flags = PF_R | PF_X;
-         m->p_flags_valid = 1;
-         m->p_paddr_valid = 1;
-         m->includes_phdrs = 1;
+      m->p_type = PT_PHDR;
+      m->p_flags = PF_R | PF_X;
+      m->p_flags_valid = 1;
+      m->p_paddr_valid = 1;
+      m->includes_phdrs = 1;
 
-         m->next = elf_tdata (abfd)->segment_map;
-         elf_tdata (abfd)->segment_map = m;
-       }
+      m->next = elf_seg_map (abfd);
+      elf_seg_map (abfd) = m;
     }
 
-  for (m = elf_tdata (abfd)->segment_map; m != NULL; m = m->next)
+  for (m = elf_seg_map (abfd) ; m != NULL; m = m->next)
     if (m->p_type == PT_LOAD)
       {
        unsigned int i;
@@ -2789,7 +2771,7 @@ elf64_hppa_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int sec_index,
       if (bfd_bread (&sig, 4, abfd) != 4)
        return FALSE;
 
-      elf_tdata (abfd)->core_signal = sig;
+      elf_tdata (abfd)->core->signal = sig;
 
       if (!_bfd_elf_make_section_from_phdr (abfd, hdr, sec_index, typename))
        return FALSE;
@@ -2846,9 +2828,6 @@ elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 {
   struct bfd_link_info *info = data;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   /* If we are not creating a shared library, and this symbol is
      referenced by a shared library but is not defined anywhere, then
      the generic code will warn that it is undefined.
@@ -2861,7 +2840,7 @@ elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 
      Ultimately we should have better controls over the generic ELF BFD
      linker code.  */
-  if (! info->relocatable
+  if (! bfd_link_relocatable (info)
       && info->unresolved_syms_in_shared_libs != RM_IGNORE
       && h->root.type == bfd_link_hash_undefined
       && h->ref_dynamic
@@ -2880,9 +2859,6 @@ elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 {
   struct bfd_link_info *info = data;
 
-  if (h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
   /* If we are not creating a shared library, and this symbol is
      referenced by a shared library but is not defined anywhere, then
      the generic code will warn that it is undefined.
@@ -2895,7 +2871,7 @@ elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
 
      Ultimately we should have better controls over the generic ELF BFD
      linker code.  */
-  if (! info->relocatable
+  if (! bfd_link_relocatable (info)
       && info->unresolved_syms_in_shared_libs != RM_IGNORE
       && h->root.type == bfd_link_hash_undefined
       && !h->ref_dynamic
@@ -2964,13 +2940,13 @@ elf_hppa_record_segment_addrs (bfd *abfd,
 static bfd_boolean
 elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
 {
-  bfd_boolean retval;
+  struct stat buf;
   struct elf64_hppa_link_hash_table *hppa_info = hppa_link_hash_table (info);
 
   if (hppa_info == NULL)
     return FALSE;
 
-  if (! info->relocatable)
+  if (! bfd_link_relocatable (info))
     {
       struct elf_link_hash_entry *gp;
       bfd_vma gp_val;
@@ -3048,7 +3024,8 @@ elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
                          info);
 
   /* Invoke the regular ELF backend linker to do all the work.  */
-  retval = bfd_elf_final_link (abfd, info);
+  if (!bfd_elf_final_link (abfd, info))
+    return FALSE;
 
   elf_link_hash_traverse (elf_hash_table (info),
                          elf_hppa_remark_useless_dynamic_symbols,
@@ -3056,10 +3033,17 @@ elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info)
 
   /* If we're producing a final executable, sort the contents of the
      unwind section. */
-  if (retval && !info->relocatable)
-    retval = elf_hppa_sort_unwind (abfd);
+  if (bfd_link_relocatable (info))
+    return TRUE;
 
-  return retval;
+  /* Do not attempt to sort non-regular files.  This is here
+     especially for configure scripts and kernel builds which run
+     tests with "ld [...] -o /dev/null".  */
+  if (stat (bfd_get_filename (abfd), &buf) != 0
+      || !S_ISREG(buf.st_mode))
+    return TRUE;
+
+  return elf_hppa_sort_unwind (abfd);
 }
 
 /* Relocate the given INSN.  VALUE should be the actual value we want
@@ -3213,7 +3197,7 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
 
   if (hppa_info == NULL)
     return bfd_reloc_notsupported;
-  
+
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   local_offsets = elf_local_got_offsets (input_bfd);
   insn = bfd_get_32 (input_bfd, hit_data);
@@ -3295,14 +3279,15 @@ elf_hppa_final_link_relocate (Elf_Internal_Rela *rel,
        if (max_branch_offset != 0
            && value + addend + max_branch_offset >= 2*max_branch_offset)
          {
-           (*_bfd_error_handler)
-             (_("%B(%A+0x%lx): cannot reach %s"),
+           _bfd_error_handler
+             /* xgettext:c-format */
+             (_("%pB(%pA+%#" PRIx64 "): cannot reach %s"),
              input_bfd,
              input_section,
-             offset,
-             eh->root.root.string);
+             (uint64_t) offset,
+             eh ? eh->root.root.string : "unknown");
            bfd_set_error (bfd_error_bad_value);
-           return bfd_reloc_notsupported;
+           return bfd_reloc_overflow;
          }
 
        /* Adjust for any field selectors.  */
@@ -3360,8 +3345,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
@@ -3394,8 +3379,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));
                  }
@@ -3569,33 +3553,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
@@ -3625,8 +3588,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);
 
@@ -3729,8 +3691,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];
@@ -3740,7 +3702,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
              {
@@ -3752,8 +3714,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);
              }
@@ -3882,14 +3843,19 @@ elf64_hppa_relocate_section (bfd *output_bfd,
          /* This is not a local symbol.  */
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
 
-         /* It seems this can happen with erroneous or unsupported 
+         /* It seems this can happen with erroneous or unsupported
             input (mixing a.out and elf in an archive, for example.)  */
          if (sym_hashes == NULL)
            return FALSE;
 
          eh = sym_hashes[r_symndx - symtab_hdr->sh_info];
 
-         while (eh->root.type == bfd_link_hash_indirect 
+         if (info->wrap_hash != NULL
+             && (input_section->flags & SEC_DEBUGGING) != 0)
+           eh = ((struct elf_link_hash_entry *)
+                 unwrap_hash_lookup (info, input_bfd, &eh->root));
+
+         while (eh->root.type == bfd_link_hash_indirect
                 || eh->root.type == bfd_link_hash_warning)
            eh = (struct elf_link_hash_entry *) eh->root.u.i.link;
 
@@ -3909,45 +3875,42 @@ elf64_hppa_relocate_section (bfd *output_bfd,
          else if (info->unresolved_syms_in_objects == RM_IGNORE
                   && ELF_ST_VISIBILITY (eh->other) == STV_DEFAULT)
            ;
-         else if (!info->relocatable
+         else if (!bfd_link_relocatable (info)
                   && elf_hppa_is_dynamic_loader_symbol (eh->root.root.string))
            continue;
-         else if (!info->relocatable)
+         else if (!bfd_link_relocatable (info))
            {
              bfd_boolean err;
-             err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
-                    || ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT);
-             if (!info->callbacks->undefined_symbol (info,
-                                                     eh->root.root.string,
-                                                     input_bfd,
-                                                     input_section,
-                                                     rel->r_offset, err))
-               return FALSE;
+
+             err = (info->unresolved_syms_in_objects == RM_DIAGNOSE
+                    && !info->warn_unresolved_syms)
+               || ELF_ST_VISIBILITY (eh->other) != STV_DEFAULT;
+
+             info->callbacks->undefined_symbol
+               (info, eh->root.root.string, input_bfd,
+                input_section, rel->r_offset, err);
            }
 
-          if (!info->relocatable
-              && 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 (! info->callbacks->undefined_symbol
-                      (info, eh_name (eh), input_bfd,
-                       input_section, rel->r_offset, FALSE))
-                    return FALSE;
-                }
-            }
+         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 && elf_discarded_section (sym_sec))
+      if (sym_sec != NULL && discarded_section (sym_sec))
        RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
-                                        rel, relend, howto, contents);
+                                        rel, 1, relend, howto, 0, contents);
 
-      if (info->relocatable)
+      if (bfd_link_relocatable (info))
        continue;
 
       r = elf_hppa_final_link_relocate (rel, input_bfd, output_bfd,
@@ -3975,14 +3938,12 @@ elf64_hppa_relocate_section (bfd *output_bfd,
                    if (sym_name == NULL)
                      return FALSE;
                    if (*sym_name == '\0')
-                     sym_name = bfd_section_name (input_bfd, sym_sec);
+                     sym_name = bfd_section_name (sym_sec);
                  }
 
-               if (!((*info->callbacks->reloc_overflow)
-                     (info, (eh ? &eh->root : NULL), sym_name,
-                      howto->name, (bfd_vma) 0, input_bfd,
-                      input_section, rel->r_offset)))
-                 return FALSE;
+               (*info->callbacks->reloc_overflow)
+                 (info, (eh ? &eh->root : NULL), sym_name, howto->name,
+                  (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
              }
              break;
            }
@@ -3993,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.  */
@@ -4035,7 +3996,7 @@ const struct elf_size_info hppa64_elf_size_info =
   bfd_elf64_swap_reloca_out
 };
 
-#define TARGET_BIG_SYM                 bfd_elf64_hppa_vec
+#define TARGET_BIG_SYM                 hppa_elf64_vec
 #define TARGET_BIG_NAME                        "elf64-hppa"
 #define ELF_ARCH                       bfd_arch_hppa
 #define ELF_TARGET_ID                  HPPA64_ELF_DATA
@@ -4064,10 +4025,10 @@ const struct elf_size_info hppa64_elf_size_info =
 
 #define elf_backend_create_dynamic_sections \
                                        elf64_hppa_create_dynamic_sections
-#define elf_backend_post_process_headers       elf64_hppa_post_process_headers
+#define elf_backend_init_file_header   elf64_hppa_init_file_header
+
+#define elf_backend_omit_section_dynsym _bfd_elf_omit_section_dynsym_all
 
-#define elf_backend_omit_section_dynsym \
-  ((bfd_boolean (*) (bfd *, struct bfd_link_info *, asection *)) bfd_true)
 #define elf_backend_adjust_dynamic_symbol \
                                        elf64_hppa_adjust_dynamic_symbol
 
@@ -4080,7 +4041,7 @@ const struct elf_size_info hppa64_elf_size_info =
                                        elf64_hppa_finish_dynamic_sections
 #define elf_backend_grok_prstatus      elf64_hppa_grok_prstatus
 #define elf_backend_grok_psinfo                elf64_hppa_grok_psinfo
+
 /* Stuff for the BFD linker: */
 #define bfd_elf64_bfd_link_hash_table_create \
        elf64_hppa_hash_table_create
@@ -4097,6 +4058,9 @@ const struct elf_size_info hppa64_elf_size_info =
 #define elf_backend_modify_segment_map \
        elf64_hppa_modify_segment_map
 
+#define elf_backend_allow_non_load_phdr \
+       elf64_hppa_allow_non_load_phdr
+
 #define elf_backend_link_output_symbol_hook \
        elf64_hppa_link_output_symbol_hook
 
@@ -4117,14 +4081,14 @@ const struct elf_size_info hppa64_elf_size_info =
 #include "elf64-target.h"
 
 #undef TARGET_BIG_SYM
-#define TARGET_BIG_SYM                 bfd_elf64_hppa_linux_vec
+#define TARGET_BIG_SYM                 hppa_elf64_linux_vec
 #undef TARGET_BIG_NAME
 #define TARGET_BIG_NAME                        "elf64-hppa-linux"
 #undef ELF_OSABI
-#define ELF_OSABI                      ELFOSABI_LINUX
-#undef elf_backend_post_process_headers
-#define elf_backend_post_process_headers _bfd_elf_set_osabi
+#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"
This page took 0.065079 seconds and 4 git commands to generate.