ubsan: som.c undefined shift in som_set_reloc_info
[binutils-gdb.git] / bfd / elfnn-ia64.c
index 84b1af1456edf7cd29bc7a33eddd4efad914358c..c27b49902239912f788eef50df615a9f05839626 100644 (file)
@@ -1,5 +1,5 @@
 /* IA-64 support for 64-bit ELF
-   Copyright (C) 1998-2018 Free Software Foundation, Inc.
+   Copyright (C) 1998-2022 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of BFD, the Binary File Descriptor library.
@@ -27,7 +27,6 @@
 #include "elf/ia64.h"
 #include "objalloc.h"
 #include "hashtab.h"
-#include "bfd_stdint.h"
 #include "elfxx-ia64.h"
 
 #define ARCH_SIZE      NN
 #define        LOG_SECTION_ALIGN       2
 #endif
 
+#define is_ia64_elf(bfd)                          \
+  (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
+   && elf_object_id (bfd) == IA64_ELF_DATA)
+
 typedef struct bfd_hash_entry *(*new_hash_entry_func)
   (struct bfd_hash_entry *, struct bfd_hash_table *, const char *);
 
@@ -74,7 +77,7 @@ struct elfNN_ia64_dyn_sym_info
     int count;
 
     /* Is this reloc against readonly section? */
-    bfd_boolean reltext;
+    bool reltext;
   } *reloc_entries;
 
   /* TRUE when the section contents have been updated.  */
@@ -140,7 +143,6 @@ struct elfNN_ia64_link_hash_table
   asection *rel_pltoff_sec;    /* Dynamic relocation section for same.  */
 
   bfd_size_type minplt_entries;        /* Number of minplt entries.  */
-  unsigned reltext : 1;                /* Are there relocs against readonly sections?  */
   unsigned self_dtpmod_done : 1;/* Has self DTPMOD entry been finished?  */
   bfd_vma self_dtpmod_offset;  /* .got offset to self DTPMOD entry.  */
   /* There are maybe R_IA64_GPREL22 relocations, including those
@@ -160,34 +162,35 @@ struct elfNN_ia64_allocate_data
 {
   struct bfd_link_info *info;
   bfd_size_type ofs;
-  bfd_boolean only_got;
+  bool only_got;
 };
 
 #define elfNN_ia64_hash_table(p) \
-  (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
-  == IA64_ELF_DATA ? ((struct elfNN_ia64_link_hash_table *) ((p)->hash)) : NULL)
+  ((is_elf_hash_table ((p)->hash)                                      \
+    && elf_hash_table_id (elf_hash_table (p)) == IA64_ELF_DATA)                \
+   ? (struct elfNN_ia64_link_hash_table *) (p)->hash : NULL)
 
 static struct elfNN_ia64_dyn_sym_info * get_dyn_sym_info
   (struct elfNN_ia64_link_hash_table *ia64_info,
    struct elf_link_hash_entry *h,
-   bfd *abfd, const Elf_Internal_Rela *rel, bfd_boolean create);
-static bfd_boolean elfNN_ia64_dynamic_symbol_p
+   bfd *abfd, const Elf_Internal_Rela *rel, bool create);
+static bool elfNN_ia64_dynamic_symbol_p
   (struct elf_link_hash_entry *h, struct bfd_link_info *info, int);
-static bfd_boolean elfNN_ia64_choose_gp
-  (bfd *abfd, struct bfd_link_info *info, bfd_boolean final);
+static bool elfNN_ia64_choose_gp
+  (bfd *abfd, struct bfd_link_info *info, bool final);
 static void elfNN_ia64_dyn_sym_traverse
   (struct elfNN_ia64_link_hash_table *ia64_info,
-   bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
+   bool (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
    void * info);
-static bfd_boolean allocate_global_data_got
+static bool allocate_global_data_got
   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
-static bfd_boolean allocate_global_fptr_got
+static bool allocate_global_fptr_got
   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
-static bfd_boolean allocate_local_got
+static bool allocate_local_got
   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
-static bfd_boolean elfNN_ia64_hpux_vec
+static bool elfNN_ia64_hpux_vec
   (const bfd_target *vec);
-static bfd_boolean allocate_dynrel_entries
+static bool allocate_dynrel_entries
   (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data);
 static asection *get_pltoff
   (bfd *abfd, struct bfd_link_info *info,
@@ -197,13 +200,24 @@ static asection *get_pltoff
 
 /* Given a ELF reloc, return the matching HOWTO structure.  */
 
-static void
+static bool
 elfNN_ia64_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED,
                          arelent *bfd_reloc,
                          Elf_Internal_Rela *elf_reloc)
 {
-  bfd_reloc->howto
-    = ia64_elf_lookup_howto ((unsigned int) ELFNN_R_TYPE (elf_reloc->r_info));
+  unsigned int r_type = ELF32_R_TYPE (elf_reloc->r_info);
+
+  bfd_reloc->howto = ia64_elf_lookup_howto (r_type);
+  if (bfd_reloc->howto == NULL)
+    {
+      /* xgettext:c-format */
+      _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
+                         abfd, r_type);
+      bfd_set_error (bfd_error_bad_value);
+      return false;
+    }
+
+  return true;
 }
 \f
 #define PLT_HEADER_SIZE                (3 * 16)
@@ -315,10 +329,10 @@ elfNN_ia64_update_short_info (asection *sec, bfd_vma offset,
     }
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_relax_section (bfd *abfd, asection *sec,
                          struct bfd_link_info *link_info,
-                         bfd_boolean *again)
+                         bool *again)
 {
   struct one_fixup
     {
@@ -335,16 +349,16 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
   Elf_Internal_Sym *isymbuf = NULL;
   struct elfNN_ia64_link_hash_table *ia64_info;
   struct one_fixup *fixups = NULL;
-  bfd_boolean changed_contents = FALSE;
-  bfd_boolean changed_relocs = FALSE;
-  bfd_boolean changed_got = FALSE;
-  bfd_boolean skip_relax_pass_0 = TRUE;
-  bfd_boolean skip_relax_pass_1 = TRUE;
+  bool changed_contents = false;
+  bool changed_relocs = false;
+  bool changed_got = false;
+  bool skip_relax_pass_0 = true;
+  bool skip_relax_pass_1 = true;
   bfd_vma gp = 0;
 
   /* Assume we're not going to change any sizes, and we'll only need
      one pass.  */
-  *again = FALSE;
+  *again = false;
 
   if (bfd_link_relocatable (link_info))
     (*link_info->callbacks->einfo)
@@ -352,7 +366,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
 
   /* Don't even try to relax for non-ELF outputs.  */
   if (!is_elf_hash_table (link_info->hash))
-    return FALSE;
+    return false;
 
   /* Nothing to do if there are no relocations or there is no need for
      the current pass.  */
@@ -360,11 +374,11 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
       || sec->reloc_count == 0
       || (link_info->relax_pass == 0 && sec->skip_relax_pass_0)
       || (link_info->relax_pass == 1 && sec->skip_relax_pass_1))
-    return TRUE;
+    return true;
 
   ia64_info = elfNN_ia64_hash_table (link_info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
 
@@ -373,7 +387,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
                     (abfd, sec, NULL, (Elf_Internal_Rela *) NULL,
                      link_info->keep_memory));
   if (internal_relocs == NULL)
-    return FALSE;
+    return false;
 
   irelend = internal_relocs + sec->reloc_count;
 
@@ -393,7 +407,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
       asection *tsec;
       struct one_fixup *f;
       bfd_size_type amt;
-      bfd_boolean is_branch;
+      bool is_branch;
       struct elfNN_ia64_dyn_sym_info *dyn_i;
       char symtype;
 
@@ -406,8 +420,8 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
          /* In pass 1, all br relaxations are done. We can skip it. */
          if (link_info->relax_pass == 1)
            continue;
-         skip_relax_pass_0 = FALSE;
-         is_branch = TRUE;
+         skip_relax_pass_0 = false;
+         is_branch = true;
          break;
 
        case R_IA64_PCREL60B:
@@ -415,10 +429,10 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
             will increase the code size. Defer it to pass 1.  */
          if (link_info->relax_pass == 0)
            {
-             skip_relax_pass_1 = FALSE;
+             skip_relax_pass_1 = false;
              continue;
            }
-         is_branch = TRUE;
+         is_branch = true;
          break;
 
        case R_IA64_GPREL22:
@@ -430,10 +444,10 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
             increase the code size. Defer it to pass 1.  */
          if (link_info->relax_pass == 0)
            {
-             skip_relax_pass_1 = FALSE;
+             skip_relax_pass_1 = false;
              continue;
            }
-         is_branch = FALSE;
+         is_branch = false;
          break;
 
        default:
@@ -471,7 +485,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
            tsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
 
          toff = isym->st_value;
-         dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, FALSE);
+         dyn_i = get_dyn_sym_info (ia64_info, NULL, abfd, irel, false);
          symtype = ELF_ST_TYPE (isym->st_info);
        }
       else
@@ -487,7 +501,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
                 || h->root.type == bfd_link_hash_warning)
            h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
-         dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, FALSE);
+         dyn_i = get_dyn_sym_info (ia64_info, h, abfd, irel, false);
 
          /* For branches to dynamic symbols, we're interested instead
             in a branch to the PLT entry.  */
@@ -594,8 +608,8 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
                  if ((irel->r_offset & 3) == 1)
                    irel->r_offset += 1;
 
-                 changed_contents = TRUE;
-                 changed_relocs = TRUE;
+                 changed_contents = true;
+                 changed_relocs = true;
                }
 
              continue;
@@ -611,8 +625,8 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
              /* Make the relocation offset point to slot 1.  */
              irel->r_offset = (irel->r_offset & ~((bfd_vma) 0x3)) + 1;
 
-             changed_contents = TRUE;
-             changed_relocs = TRUE;
+             changed_contents = true;
+             changed_relocs = true;
              continue;
            }
 
@@ -725,8 +739,8 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
              != bfd_reloc_ok)
            goto error_return;
 
-         changed_contents = TRUE;
-         changed_relocs = TRUE;
+         changed_contents = true;
+         changed_relocs = true;
        }
       else
        {
@@ -737,7 +751,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
              gp = _bfd_get_gp_value (obfd);
              if (gp == 0)
                {
-                 if (!elfNN_ia64_choose_gp (obfd, link_info, FALSE))
+                 if (!elfNN_ia64_choose_gp (obfd, link_info, false))
                    goto error_return;
                  gp = _bfd_get_gp_value (obfd);
                }
@@ -756,7 +770,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
            {
              irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
                                           R_IA64_GPREL22);
-             changed_relocs = TRUE;
+             changed_relocs = true;
              if (dyn_i->want_gotx)
                {
                  dyn_i->want_gotx = 0;
@@ -771,8 +785,8 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
            {
              ia64_elf_relax_ldxmov (contents, roff);
              irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
-             changed_contents = TRUE;
-             changed_relocs = TRUE;
+             changed_contents = true;
+             changed_relocs = true;
            }
        }
     }
@@ -842,7 +856,7 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
          if (bfd_link_pic (link_info)
              && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
            ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
-         data.only_got = TRUE;
+         data.only_got = true;
          elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries,
                                       &data);
        }
@@ -856,41 +870,39 @@ elfNN_ia64_relax_section (bfd *abfd, asection *sec,
     }
 
   *again = changed_contents || changed_relocs;
-  return TRUE;
+  return true;
 
  error_return:
-  if (isymbuf != NULL && (unsigned char *) isymbuf != symtab_hdr->contents)
+  if ((unsigned char *) isymbuf != symtab_hdr->contents)
     free (isymbuf);
-  if (contents != NULL
-      && elf_section_data (sec)->this_hdr.contents != contents)
+  if (elf_section_data (sec)->this_hdr.contents != contents)
     free (contents);
-  if (internal_relocs != NULL
-      && elf_section_data (sec)->relocs != internal_relocs)
+  if (elf_section_data (sec)->relocs != internal_relocs)
     free (internal_relocs);
-  return FALSE;
+  return false;
 }
 #undef skip_relax_pass_0
 #undef skip_relax_pass_1
 \f
 /* Return TRUE if NAME is an unwind table section name.  */
 
-static inline bfd_boolean
+static inline bool
 is_unwind_section_name (bfd *abfd, const char *name)
 {
   if (elfNN_ia64_hpux_vec (abfd->xvec)
       && !strcmp (name, ELF_STRING_ia64_unwind_hdr))
-    return FALSE;
+    return false;
 
-  return ((CONST_STRNEQ (name, ELF_STRING_ia64_unwind)
-          && ! CONST_STRNEQ (name, ELF_STRING_ia64_unwind_info))
-         || CONST_STRNEQ (name, ELF_STRING_ia64_unwind_once));
+  return ((startswith (name, ELF_STRING_ia64_unwind)
+          && ! startswith (name, ELF_STRING_ia64_unwind_info))
+         || startswith (name, ELF_STRING_ia64_unwind_once));
 }
 
 /* Handle an IA-64 specific section when reading an object file.  This
    is called when bfd_section_from_shdr finds a section with an unknown
    type.  */
 
-static bfd_boolean
+static bool
 elfNN_ia64_section_from_shdr (bfd *abfd,
                              Elf_Internal_Shdr *hdr,
                              const char *name,
@@ -909,17 +921,17 @@ elfNN_ia64_section_from_shdr (bfd *abfd,
 
     case SHT_IA_64_EXT:
       if (strcmp (name, ELF_STRING_ia64_archext) != 0)
-       return FALSE;
+       return false;
       break;
 
     default:
-      return FALSE;
+      return false;
     }
 
   if (! _bfd_elf_make_section_from_shdr (abfd, hdr, name, shindex))
-    return FALSE;
+    return false;
 
-  return TRUE;
+  return true;
 }
 
 /* Convert IA-64 specific section flags to bfd internal section flags.  */
@@ -927,26 +939,25 @@ elfNN_ia64_section_from_shdr (bfd *abfd,
 /* ??? There is no bfd internal flag equivalent to the SHF_IA_64_NORECOV
    flag.  */
 
-static bfd_boolean
-elfNN_ia64_section_flags (flagword *flags,
-                         const Elf_Internal_Shdr *hdr)
+static bool
+elfNN_ia64_section_flags (const Elf_Internal_Shdr *hdr)
 {
   if (hdr->sh_flags & SHF_IA_64_SHORT)
-    *flags |= SEC_SMALL_DATA;
+    hdr->bfd_section->flags |= SEC_SMALL_DATA;
 
-  return TRUE;
+  return true;
 }
 
 /* Set the correct type for an IA-64 ELF section.  We do this by the
    section name, which is a hack, but ought to work.  */
 
-static bfd_boolean
+static bool
 elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
                          asection *sec)
 {
   const char *name;
 
-  name = bfd_get_section_name (abfd, sec);
+  name = bfd_section_name (sec);
 
   if (is_unwind_section_name (abfd, name))
     {
@@ -986,15 +997,14 @@ elfNN_ia64_fake_sections (bfd *abfd, Elf_Internal_Shdr *hdr,
   if (elfNN_ia64_hpux_vec (abfd->xvec) && (sec->flags & SHF_TLS))
     hdr->sh_flags |= SHF_IA_64_HP_TLS;
 
-  return TRUE;
+  return true;
 }
 
 /* The final processing done just before writing out an IA-64 ELF
    object file.  */
 
-static void
-elfNN_ia64_final_write_processing (bfd *abfd,
-                                  bfd_boolean linker ATTRIBUTE_UNUSED)
+static bool
+elfNN_ia64_final_write_processing (bfd *abfd)
 {
   Elf_Internal_Shdr *hdr;
   asection *s;
@@ -1024,14 +1034,15 @@ elfNN_ia64_final_write_processing (bfd *abfd,
        flags |= EF_IA_64_ABI64;
 
       elf_elfheader(abfd)->e_flags = flags;
-      elf_flags_init (abfd) = TRUE;
+      elf_flags_init (abfd) = true;
     }
+  return _bfd_elf_final_write_processing (abfd);
 }
 
 /* Hook called by the linker routine which adds symbols from an object
    file.  We use it to put .comm items in .sbss, and not .bss.  */
 
-static bfd_boolean
+static bool
 elfNN_ia64_add_symbol_hook (bfd *abfd,
                            struct bfd_link_info *info,
                            Elf_Internal_Sym *sym,
@@ -1054,16 +1065,17 @@ elfNN_ia64_add_symbol_hook (bfd *abfd,
          scomm = bfd_make_section_with_flags (abfd, ".scommon",
                                               (SEC_ALLOC
                                                | SEC_IS_COMMON
+                                               | SEC_SMALL_DATA
                                                | SEC_LINKER_CREATED));
          if (scomm == NULL)
-           return FALSE;
+           return false;
        }
 
       *secp = scomm;
       *valp = sym->st_size;
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Return the number of additional phdrs we will need.  */
@@ -1088,7 +1100,7 @@ elfNN_ia64_additional_program_headers (bfd *abfd,
   return ret;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_modify_segment_map (bfd *abfd,
                               struct bfd_link_info *info ATTRIBUTE_UNUSED)
 {
@@ -1109,7 +1121,7 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
          m = ((struct elf_segment_map *)
               bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
          if (m == NULL)
-           return FALSE;
+           return false;
 
          m->p_type = PT_IA_64_ARCHEXT;
          m->count = 1;
@@ -1157,7 +1169,7 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
              m = ((struct elf_segment_map *)
                   bfd_zalloc (abfd, (bfd_size_type) sizeof *m));
              if (m == NULL)
-               return FALSE;
+               return false;
 
              m->p_type = PT_IA_64_UNWIND;
              m->count = 1;
@@ -1173,16 +1185,15 @@ elfNN_ia64_modify_segment_map (bfd *abfd,
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* Turn on PF_IA_64_NORECOV if needed.  This involves traversing all of
    the input sections for each output section in the segment and testing
    for SHF_IA_64_NORECOV on each.  */
 
-static bfd_boolean
-elfNN_ia64_modify_program_headers (bfd *abfd,
-                                  struct bfd_link_info *info ATTRIBUTE_UNUSED)
+static bool
+elfNN_ia64_modify_headers (bfd *abfd, struct bfd_link_info *info)
 {
   struct elf_obj_tdata *tdata = elf_tdata (abfd);
   struct elf_segment_map *m;
@@ -1214,13 +1225,13 @@ elfNN_ia64_modify_program_headers (bfd *abfd,
       found:;
       }
 
-  return TRUE;
+  return _bfd_elf_modify_headers (abfd, info);
 }
 
 /* According to the Tahoe assembler spec, all labels starting with a
    '.' are local.  */
 
-static bfd_boolean
+static bool
 elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
                                const char *name)
 {
@@ -1229,11 +1240,11 @@ elfNN_ia64_is_local_label_name (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* Should we do dynamic things to this symbol?  */
 
-static bfd_boolean
+static bool
 elfNN_ia64_dynamic_symbol_p (struct elf_link_hash_entry *h,
                             struct bfd_link_info *info, int r_type)
 {
-  bfd_boolean ignore_protected
+  bool ignore_protected
     = ((r_type & 0xf8) == 0x40         /* FPTR relocs */
        || (r_type & 0xf8) == 0x50);    /* LTOFF_FPTR relocs */
 
@@ -1298,8 +1309,7 @@ elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
       struct elfNN_ia64_dyn_sym_info *dyn_i;
       unsigned int count;
 
-      if (dir->info)
-       free (dir->info);
+      free (dir->info);
 
       dir->info = ind->info;
       dir->count = ind->count;
@@ -1335,7 +1345,7 @@ elfNN_ia64_hash_copy_indirect (struct bfd_link_info *info,
 static void
 elfNN_ia64_hash_hide_symbol (struct bfd_link_info *info,
                             struct elf_link_hash_entry *xh,
-                            bfd_boolean force_local)
+                            bool force_local)
 {
   struct elfNN_ia64_link_hash_entry *h;
   struct elfNN_ia64_dyn_sym_info *dyn_i;
@@ -1380,44 +1390,38 @@ elfNN_ia64_local_htab_eq (const void *ptr1, const void *ptr2)
 
 /* Free the global elfNN_ia64_dyn_sym_info array.  */
 
-static bfd_boolean
-elfNN_ia64_global_dyn_info_free (void **xentry,
-                                void * unused ATTRIBUTE_UNUSED)
+static bool
+elfNN_ia64_global_dyn_info_free (struct elf_link_hash_entry *xentry,
+                                void *unused ATTRIBUTE_UNUSED)
 {
   struct elfNN_ia64_link_hash_entry *entry
     = (struct elfNN_ia64_link_hash_entry *) xentry;
 
-  if (entry->info)
-    {
-      free (entry->info);
-      entry->info = NULL;
-      entry->count = 0;
-      entry->sorted_count = 0;
-      entry->size = 0;
-    }
+  free (entry->info);
+  entry->info = NULL;
+  entry->count = 0;
+  entry->sorted_count = 0;
+  entry->size = 0;
 
-  return TRUE;
+  return true;
 }
 
 /* Free the local elfNN_ia64_dyn_sym_info array.  */
 
-static bfd_boolean
+static int
 elfNN_ia64_local_dyn_info_free (void **slot,
                                void * unused ATTRIBUTE_UNUSED)
 {
   struct elfNN_ia64_local_hash_entry *entry
     = (struct elfNN_ia64_local_hash_entry *) *slot;
 
-  if (entry->info)
-    {
-      free (entry->info);
-      entry->info = NULL;
-      entry->count = 0;
-      entry->sorted_count = 0;
-      entry->size = 0;
-    }
+  free (entry->info);
+  entry->info = NULL;
+  entry->count = 0;
+  entry->sorted_count = 0;
+  entry->size = 0;
 
-  return TRUE;
+  return true;
 }
 
 /* Destroy IA-64 linker hash table.  */
@@ -1471,6 +1475,7 @@ elfNN_ia64_hash_table_create (bfd *abfd)
       return NULL;
     }
   ret->root.root.hash_table_free = elfNN_ia64_link_hash_table_free;
+  ret->root.dt_pltgot_required = true;
 
   return &ret->root.root;
 }
@@ -1479,12 +1484,12 @@ elfNN_ia64_hash_table_create (bfd *abfd)
 
 struct elfNN_ia64_dyn_sym_traverse_data
 {
-  bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *);
+  bool (*func) (struct elfNN_ia64_dyn_sym_info *, void *);
   void * data;
 };
 
-static bfd_boolean
-elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
+static bool
+elfNN_ia64_global_dyn_sym_thunk (struct elf_link_hash_entry *xentry,
                                 void * xdata)
 {
   struct elfNN_ia64_link_hash_entry *entry
@@ -1498,11 +1503,11 @@ elfNN_ia64_global_dyn_sym_thunk (struct bfd_hash_entry *xentry,
        count != 0;
        count--, dyn_i++)
     if (! (*data->func) (dyn_i, data->data))
-      return FALSE;
-  return TRUE;
+      return false;
+  return true;
 }
 
-static bfd_boolean
+static int
 elfNN_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
 {
   struct elfNN_ia64_local_hash_entry *entry
@@ -1516,13 +1521,14 @@ elfNN_ia64_local_dyn_sym_thunk (void **slot, void * xdata)
        count != 0;
        count--, dyn_i++)
     if (! (*data->func) (dyn_i, data->data))
-      return FALSE;
-  return TRUE;
+      return false;
+  return true;
 }
 
 static void
 elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
-                            bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, void *),
+                            bool (*func) (struct elfNN_ia64_dyn_sym_info *,
+                                          void *),
                             void * data)
 {
   struct elfNN_ia64_dyn_sym_traverse_data xdata;
@@ -1536,7 +1542,7 @@ elfNN_ia64_dyn_sym_traverse (struct elfNN_ia64_link_hash_table *ia64_info,
                 elfNN_ia64_local_dyn_sym_thunk, &xdata);
 }
 \f
-static bfd_boolean
+static bool
 elfNN_ia64_create_dynamic_sections (bfd *abfd,
                                    struct bfd_link_info *info)
 {
@@ -1544,23 +1550,22 @@ elfNN_ia64_create_dynamic_sections (bfd *abfd,
   asection *s;
 
   if (! _bfd_elf_create_dynamic_sections (abfd, info))
-    return FALSE;
+    return false;
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   {
-    flagword flags = bfd_get_section_flags (abfd, ia64_info->root.sgot);
-    bfd_set_section_flags (abfd, ia64_info->root.sgot,
-                          SEC_SMALL_DATA | flags);
+    flagword flags = bfd_section_flags (ia64_info->root.sgot);
+    bfd_set_section_flags (ia64_info->root.sgot, SEC_SMALL_DATA | flags);
     /* The .got section is always aligned at 8 bytes.  */
-    if (! bfd_set_section_alignment (abfd, ia64_info->root.sgot, 3))
-      return FALSE;
+    if (!bfd_set_section_alignment (ia64_info->root.sgot, 3))
+      return false;
   }
 
   if (!get_pltoff (abfd, info, ia64_info))
-    return FALSE;
+    return false;
 
   s = bfd_make_section_anyway_with_flags (abfd, ".rela.IA_64.pltoff",
                                          (SEC_ALLOC | SEC_LOAD
@@ -1569,18 +1574,18 @@ elfNN_ia64_create_dynamic_sections (bfd *abfd,
                                           | SEC_LINKER_CREATED
                                           | SEC_READONLY));
   if (s == NULL
-      || !bfd_set_section_alignment (abfd, s, LOG_SECTION_ALIGN))
-    return FALSE;
+      || !bfd_set_section_alignment (s, LOG_SECTION_ALIGN))
+    return false;
   ia64_info->rel_pltoff_sec = s;
 
-  return TRUE;
+  return true;
 }
 
 /* Find and/or create a hash entry for local symbol.  */
 static struct elfNN_ia64_local_hash_entry *
 get_local_sym_hash (struct elfNN_ia64_link_hash_table *ia64_info,
                    bfd *abfd, const Elf_Internal_Rela *rel,
-                   bfd_boolean create)
+                   bool create)
 {
   struct elfNN_ia64_local_hash_entry e, *ret;
   asection *sec = abfd->sections;
@@ -1810,7 +1815,7 @@ sort_dyn_sym_info (struct elfNN_ia64_dyn_sym_info *info,
 static struct elfNN_ia64_dyn_sym_info *
 get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
                  struct elf_link_hash_entry *h, bfd *abfd,
-                 const Elf_Internal_Rela *rel, bfd_boolean create)
+                 const Elf_Internal_Rela *rel, bool create)
 {
   struct elfNN_ia64_dyn_sym_info **info_p, *info, *dyn_i, key;
   unsigned int *count_p, *sorted_count_p, *size_p;
@@ -1863,18 +1868,16 @@ get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
              key.addend = addend;
              dyn_i = bsearch (&key, info, sorted_count,
                               sizeof (*info), addend_compare);
-
              if (dyn_i)
-               {
-                 return dyn_i;
-               }
+               return dyn_i;
            }
 
-         /* Do a quick check for the last inserted entry.  */
-         dyn_i = info + count - 1;
-         if (dyn_i->addend == addend)
+         if (count != 0)
            {
-             return dyn_i;
+             /* Do a quick check for the last inserted entry.  */
+             dyn_i = info + count - 1;
+             if (dyn_i->addend == addend)
+               return dyn_i;
            }
        }
 
@@ -1902,7 +1905,7 @@ get_dyn_sym_info (struct elfNN_ia64_link_hash_table *ia64_info,
       *size_p = size;
       *info_p = info;
 
-has_space:
+    has_space:
       /* Append the new one to the array.  */
       dyn_i = info + count;
       memset (dyn_i, 0, sizeof (*dyn_i));
@@ -1928,19 +1931,23 @@ has_space:
       if (size != count)
        {
          amt = count * sizeof (*info);
-         info = bfd_malloc (amt);
-         if (info != NULL)
-           {
-             memcpy (info, *info_p, amt);
-             free (*info_p);
-             *size_p = count;
-             *info_p = info;
-           }
+         info = bfd_realloc (info, amt);
+         *size_p = count;
+         if (info == NULL && count != 0)
+           /* realloc should never fail since we are reducing size here,
+              but if it does use the old array.  */
+           info = *info_p;
+         else
+           *info_p = info;
        }
 
-      key.addend = addend;
-      dyn_i = bsearch (&key, info, count,
-                      sizeof (*info), addend_compare);
+      if (count == 0)
+       dyn_i = NULL;
+      else
+       {
+         key.addend = addend;
+         dyn_i = bsearch (&key, info, count, sizeof (*info), addend_compare);
+       }
     }
 
   return dyn_i;
@@ -1967,11 +1974,11 @@ get_got (bfd *abfd, struct bfd_link_info *info,
       got = ia64_info->root.sgot;
 
       /* The .got section is always aligned at 8 bytes.  */
-      if (!bfd_set_section_alignment (abfd, got, 3))
+      if (!bfd_set_section_alignment (got, 3))
        return NULL;
 
-      flags = bfd_get_section_flags (abfd, got);
-      if (! bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags))
+      flags = bfd_section_flags (got);
+      if (!bfd_set_section_flags (got, SEC_SMALL_DATA | flags))
        return NULL;
     }
 
@@ -2006,7 +2013,7 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
                                                     ? 0 : SEC_READONLY)
                                                  | SEC_LINKER_CREATED));
       if (!fptr
-         || !bfd_set_section_alignment (abfd, fptr, 4))
+         || !bfd_set_section_alignment (fptr, 4))
        {
          BFD_ASSERT (0);
          return NULL;
@@ -2024,8 +2031,7 @@ get_fptr (bfd *abfd, struct bfd_link_info *info,
                                                          | SEC_LINKER_CREATED
                                                          | SEC_READONLY));
          if (fptr_rel == NULL
-             || !bfd_set_section_alignment (abfd, fptr_rel,
-                                            LOG_SECTION_ALIGN))
+             || !bfd_set_section_alignment (fptr_rel, LOG_SECTION_ALIGN))
            {
              BFD_ASSERT (0);
              return NULL;
@@ -2061,7 +2067,7 @@ get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                                    | SEC_SMALL_DATA
                                                    | SEC_LINKER_CREATED));
       if (!pltoff
-         || !bfd_set_section_alignment (abfd, pltoff, 4))
+         || !bfd_set_section_alignment (pltoff, 4))
        {
          BFD_ASSERT (0);
          return NULL;
@@ -2076,7 +2082,7 @@ get_pltoff (bfd *abfd, struct bfd_link_info *info ATTRIBUTE_UNUSED,
 static asection *
 get_reloc_section (bfd *abfd,
                   struct elfNN_ia64_link_hash_table *ia64_info,
-                  asection *sec, bfd_boolean create)
+                  asection *sec, bool create)
 {
   const char *srel_name;
   asection *srel;
@@ -2102,17 +2108,16 @@ get_reloc_section (bfd *abfd,
                                                  | SEC_LINKER_CREATED
                                                  | SEC_READONLY));
       if (srel == NULL
-         || !bfd_set_section_alignment (dynobj, srel,
-                                        LOG_SECTION_ALIGN))
+         || !bfd_set_section_alignment (srel, LOG_SECTION_ALIGN))
        return NULL;
     }
 
   return srel;
 }
 
-static bfd_boolean
+static bool
 count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
-                asection *srel, int type, bfd_boolean reltext)
+                asection *srel, int type, bool reltext)
 {
   struct elfNN_ia64_dyn_reloc_entry *rent;
 
@@ -2125,7 +2130,7 @@ count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
       rent = ((struct elfNN_ia64_dyn_reloc_entry *)
              bfd_alloc (abfd, (bfd_size_type) sizeof (*rent)));
       if (!rent)
-       return FALSE;
+       return false;
 
       rent->next = dyn_i->reloc_entries;
       rent->srel = srel;
@@ -2136,10 +2141,10 @@ count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
   rent->reltext = reltext;
   rent->count++;
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
                         asection *sec,
                         const Elf_Internal_Rela *relocs)
@@ -2165,15 +2170,15 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
   int need_entry;
   struct elf_link_hash_entry *h;
   unsigned long r_symndx;
-  bfd_boolean maybe_dynamic;
+  bool maybe_dynamic;
 
   if (bfd_link_relocatable (info))
-    return TRUE;
+    return true;
 
   symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   got = fptr = srel = pltoff = NULL;
 
@@ -2196,9 +2201,6 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       else
        h = NULL;
 
-      if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
-       continue;
-
       /* We can only get preliminary data on whether a symbol is
         locally or externally defined, as not all of the input files
         have yet been processed.  Do something with what we know, as
@@ -2344,8 +2346,8 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
             abfd, 0, (bfd_vma) 0);
        }
 
-      if (get_dyn_sym_info (ia64_info, h, abfd, rel, TRUE) == NULL)
-       return FALSE;
+      if (get_dyn_sym_info (ia64_info, h, abfd, rel, true) == NULL)
+       return false;
     }
 
   /* Now, we only do lookup without insertion, which is very fast
@@ -2373,9 +2375,6 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       else
        h = NULL;
 
-      if (h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
-       continue;
-
       /* We can only get preliminary data on whether a symbol is
         locally or externally defined, as not all of the input files
         have yet been processed.  Do something with what we know, as
@@ -2516,7 +2515,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
       if (!need_entry)
        continue;
 
-      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, FALSE);
+      dyn_i = get_dyn_sym_info (ia64_info, h, abfd, rel, false);
 
       /* Record whether or not this is a local symbol.  */
       dyn_i->h = h;
@@ -2529,7 +2528,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              got = get_got (abfd, info, ia64_info);
              if (!got)
-               return FALSE;
+               return false;
            }
          if (need_entry & NEED_GOT)
            dyn_i->want_got = 1;
@@ -2548,7 +2547,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              fptr = get_fptr (abfd, info, ia64_info);
              if (!fptr)
-               return FALSE;
+               return false;
            }
 
          /* FPTRs for shared libraries are allocated by the dynamic
@@ -2558,7 +2557,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              if (! (bfd_elf_link_record_local_dynamic_symbol
                     (info, abfd, (long) r_symndx)))
-               return FALSE;
+               return false;
            }
 
          dyn_i->want_fptr = 1;
@@ -2582,7 +2581,7 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
            {
              pltoff = get_pltoff (abfd, info, ia64_info);
              if (!pltoff)
-               return FALSE;
+               return false;
            }
 
          dyn_i->want_pltoff = 1;
@@ -2591,23 +2590,23 @@ elfNN_ia64_check_relocs (bfd *abfd, struct bfd_link_info *info,
        {
          if (!srel)
            {
-             srel = get_reloc_section (abfd, ia64_info, sec, TRUE);
+             srel = get_reloc_section (abfd, ia64_info, sec, true);
              if (!srel)
-               return FALSE;
+               return false;
            }
          if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
                                (sec->flags & SEC_READONLY) != 0))
-           return FALSE;
+           return false;
        }
     }
 
-  return TRUE;
+  return true;
 }
 
 /* For cleanliness, and potentially faster dynamic loading, allocate
    external GOT entries first.  */
 
-static bfd_boolean
+static bool
 allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
                          void * data)
 {
@@ -2638,7 +2637,7 @@ allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
 
          ia64_info = elfNN_ia64_hash_table (x->info);
          if (ia64_info == NULL)
-           return FALSE;
+           return false;
 
          if (ia64_info->self_dtpmod_offset == (bfd_vma) -1)
            {
@@ -2653,12 +2652,12 @@ allocate_global_data_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
       dyn_i->dtprel_offset = x->ofs;
       x->ofs += 8;
     }
-  return TRUE;
+  return true;
 }
 
 /* Next, allocate all the GOT entries used by LTOFF_FPTR relocs.  */
 
-static bfd_boolean
+static bool
 allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
                          void * data)
 {
@@ -2671,12 +2670,12 @@ allocate_global_fptr_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
       dyn_i->got_offset = x->ofs;
       x->ofs += 8;
     }
-  return TRUE;
+  return true;
 }
 
 /* Lastly, allocate all the GOT entries for local data.  */
 
-static bfd_boolean
+static bool
 allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
                    void * data)
 {
@@ -2688,7 +2687,7 @@ allocate_local_got (struct elfNN_ia64_dyn_sym_info *dyn_i,
       dyn_i->got_offset = x->ofs;
       x->ofs += 8;
     }
-  return TRUE;
+  return true;
 }
 
 /* Search for the index of a global symbol in it's defining object file.  */
@@ -2712,7 +2711,7 @@ global_sym_index (struct elf_link_hash_entry *h)
 /* Allocate function descriptors.  We can do these for every function
    in a main executable that is not exported.  */
 
-static bfd_boolean
+static bool
 allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
 {
   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
@@ -2728,8 +2727,7 @@ allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
 
       if (!bfd_link_executable (x->info)
          && (!h
-             || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
-                 && !UNDEFWEAK_NO_DYNAMIC_RELOC (x->info, h))
+             || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
              || (h->root.type != bfd_link_hash_undefweak
                  && h->root.type != bfd_link_hash_undefined)))
        {
@@ -2741,7 +2739,7 @@ allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
              if (!bfd_elf_link_record_local_dynamic_symbol
                    (x->info, h->root.u.def.section->owner,
                     global_sym_index (h)))
-               return FALSE;
+               return false;
            }
 
          dyn_i->want_fptr = 0;
@@ -2754,12 +2752,12 @@ allocate_fptr (struct elfNN_ia64_dyn_sym_info *dyn_i, void * data)
       else
        dyn_i->want_fptr = 0;
     }
-  return TRUE;
+  return true;
 }
 
 /* Allocate all the minimal PLT entries.  */
 
-static bfd_boolean
+static bool
 allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
                      void * data)
 {
@@ -2791,12 +2789,12 @@ allocate_plt_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
          dyn_i->want_plt2 = 0;
        }
     }
-  return TRUE;
+  return true;
 }
 
 /* Allocate all the full PLT entries.  */
 
-static bfd_boolean
+static bool
 allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
                       void * data)
 {
@@ -2815,7 +2813,7 @@ allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
        h = (struct elf_link_hash_entry *) h->root.u.i.link;
       dyn_i->h->plt.offset = ofs;
     }
-  return TRUE;
+  return true;
 }
 
 /* Allocate all the PLTOFF entries requested by relocations and
@@ -2823,7 +2821,7 @@ allocate_plt2_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
    because the latter are not necessarily addressable by the GP.
    ??? Relaxation might be able to determine that they are.  */
 
-static bfd_boolean
+static bool
 allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
                         void * data)
 {
@@ -2834,32 +2832,32 @@ allocate_pltoff_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
       dyn_i->pltoff_offset = x->ofs;
       x->ofs += 16;
     }
-  return TRUE;
+  return true;
 }
 
 /* Allocate dynamic relocations for those symbols that turned out
    to be dynamic.  */
 
-static bfd_boolean
+static bool
 allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
                         void * data)
 {
   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
   struct elfNN_ia64_link_hash_table *ia64_info;
   struct elfNN_ia64_dyn_reloc_entry *rent;
-  bfd_boolean dynamic_symbol, shared, resolved_zero;
+  bool dynamic_symbol, shared, resolved_zero;
 
   ia64_info = elfNN_ia64_hash_table (x->info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   /* Note that this can't be used in relation to FPTR relocs below.  */
   dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0);
 
   shared = bfd_link_pic (x->info);
   resolved_zero = (dyn_i->h
-                  && UNDEFWEAK_NO_DYNAMIC_RELOC (x->info,
-                                                      dyn_i->h));
+                  && ELF_ST_VISIBILITY (dyn_i->h->other)
+                  && dyn_i->h->root.type == bfd_link_hash_undefweak);
 
   /* Take care of the GOT and PLT relocations.  */
 
@@ -2884,7 +2882,7 @@ allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
     ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
 
   if (x->only_got)
-    return TRUE;
+    return true;
 
   if (ia64_info->rel_fptr_sec && dyn_i->want_fptr)
     {
@@ -2951,14 +2949,14 @@ allocate_dynrel_entries (struct elfNN_ia64_dyn_sym_info *dyn_i,
          abort ();
        }
       if (rent->reltext)
-       ia64_info->reltext = 1;
+       x->info->flags |= DF_TEXTREL;
       rent->srel->size += sizeof (ElfNN_External_Rela) * count;
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
                                  struct elf_link_hash_entry *h)
 {
@@ -2974,7 +2972,7 @@ elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
       BFD_ASSERT (def->root.type == bfd_link_hash_defined);
       h->root.u.def.section = def->root.u.def.section;
       h->root.u.def.value = def->root.u.def.value;
-      return TRUE;
+      return true;
     }
 
   /* If this is a reference to a symbol defined by a dynamic object which
@@ -2984,10 +2982,10 @@ elfNN_ia64_adjust_dynamic_symbol (struct bfd_link_info *info ATTRIBUTE_UNUSED,
      But IA-64 code is canonically PIC, so as a rule we can avoid this sort
      of hackery.  */
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
                                  struct bfd_link_info *info)
 {
@@ -2995,11 +2993,10 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
   struct elfNN_ia64_link_hash_table *ia64_info;
   asection *sec;
   bfd *dynobj;
-  bfd_boolean relplt = FALSE;
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
   dynobj = ia64_info->root.dynobj;
   ia64_info->self_dtpmod_offset = (bfd_vma) -1;
   BFD_ASSERT(dynobj != NULL);
@@ -3085,7 +3082,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
       if (bfd_link_pic (info) && ia64_info->self_dtpmod_offset != (bfd_vma) -1)
        ia64_info->root.srelgot->size += sizeof (ElfNN_External_Rela);
-      data.only_got = FALSE;
+      data.only_got = false;
       elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_dynrel_entries, &data);
     }
 
@@ -3093,7 +3090,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
      Allocate memory for them.  */
   for (sec = dynobj->sections; sec != NULL; sec = sec->next)
     {
-      bfd_boolean strip;
+      bool strip;
 
       if (!(sec->flags & SEC_LINKER_CREATED))
        continue;
@@ -3109,7 +3106,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
       strip = (sec->size == 0);
 
       if (sec == ia64_info->root.sgot)
-       strip = FALSE;
+       strip = false;
       else if (sec == ia64_info->root.srelgot)
        {
          if (strip)
@@ -3149,7 +3146,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
            ia64_info->rel_pltoff_sec = NULL;
          else
            {
-             relplt = TRUE;
+             ia64_info->root.dt_jmprel_required = true;
              /* We use the reloc_count field as a counter if we need to
                 copy relocs into the output file.  */
              sec->reloc_count = 0;
@@ -3161,11 +3158,11 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
 
          /* 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, ".got.plt") == 0)
-           strip = FALSE;
-         else if (CONST_STRNEQ (name, ".rel"))
+           strip = false;
+         else if (startswith (name, ".rel"))
            {
              if (!strip)
                {
@@ -3185,7 +3182,7 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
          /* Allocate memory for the section contents.  */
          sec->contents = (bfd_byte *) bfd_zalloc (dynobj, sec->size);
          if (sec->contents == NULL && sec->size != 0)
-           return FALSE;
+           return false;
        }
     }
 
@@ -3195,46 +3192,19 @@ elfNN_ia64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
         later (in finish_dynamic_sections) but we must add the entries now
         so that we get the correct size for the .dynamic section.  */
 
-      if (bfd_link_executable (info))
-       {
-         /* The DT_DEBUG entry is filled in by the dynamic linker and used
-            by the debugger.  */
 #define add_dynamic_entry(TAG, VAL) \
   _bfd_elf_add_dynamic_entry (info, TAG, VAL)
 
-         if (!add_dynamic_entry (DT_DEBUG, 0))
-           return FALSE;
-       }
+      if (!_bfd_elf_add_dynamic_tags (output_bfd, info, true))
+       return false;
 
       if (!add_dynamic_entry (DT_IA_64_PLT_RESERVE, 0))
-       return FALSE;
-      if (!add_dynamic_entry (DT_PLTGOT, 0))
-       return FALSE;
-
-      if (relplt)
-       {
-         if (!add_dynamic_entry (DT_PLTRELSZ, 0)
-             || !add_dynamic_entry (DT_PLTREL, DT_RELA)
-             || !add_dynamic_entry (DT_JMPREL, 0))
-           return FALSE;
-       }
-
-      if (!add_dynamic_entry (DT_RELA, 0)
-         || !add_dynamic_entry (DT_RELASZ, 0)
-         || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
-       return FALSE;
-
-      if (ia64_info->reltext)
-       {
-         if (!add_dynamic_entry (DT_TEXTREL, 0))
-           return FALSE;
-         info->flags |= DF_TEXTREL;
-       }
+       return false;
     }
 
   /* ??? Perhaps force __gp local.  */
 
-  return TRUE;
+  return true;
 }
 
 static void
@@ -3278,7 +3248,7 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
 {
   struct elfNN_ia64_link_hash_table *ia64_info;
   asection *got_sec;
-  bfd_boolean done;
+  bool done;
   bfd_vma got_offset;
 
   ia64_info = elfNN_ia64_hash_table (info);
@@ -3291,19 +3261,19 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
     {
     case R_IA64_TPREL64LSB:
       done = dyn_i->tprel_done;
-      dyn_i->tprel_done = TRUE;
+      dyn_i->tprel_done = true;
       got_offset = dyn_i->tprel_offset;
       break;
     case R_IA64_DTPMOD64LSB:
       if (dyn_i->dtpmod_offset != ia64_info->self_dtpmod_offset)
        {
          done = dyn_i->dtpmod_done;
-         dyn_i->dtpmod_done = TRUE;
+         dyn_i->dtpmod_done = true;
        }
       else
        {
          done = ia64_info->self_dtpmod_done;
-         ia64_info->self_dtpmod_done = TRUE;
+         ia64_info->self_dtpmod_done = true;
          dynindx = 0;
        }
       got_offset = dyn_i->dtpmod_offset;
@@ -3311,12 +3281,12 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
     case R_IA64_DTPREL32LSB:
     case R_IA64_DTPREL64LSB:
       done = dyn_i->dtprel_done;
-      dyn_i->dtprel_done = TRUE;
+      dyn_i->dtprel_done = true;
       got_offset = dyn_i->dtprel_offset;
       break;
     default:
       done = dyn_i->got_done;
-      dyn_i->got_done = TRUE;
+      dyn_i->got_done = true;
       got_offset = dyn_i->got_offset;
       break;
     }
@@ -3331,8 +3301,7 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
       /* Install a dynamic relocation if needed.  */
       if (((bfd_link_pic (info)
            && (!dyn_i->h
-               || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
-                   && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
+               || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
                || dyn_i->h->root.type != bfd_link_hash_undefweak)
            && dyn_r_type != R_IA64_DTPREL32LSB
            && dyn_r_type != R_IA64_DTPREL64LSB)
@@ -3391,7 +3360,7 @@ set_got_entry (bfd *abfd, struct bfd_link_info *info,
                  dyn_r_type = R_IA64_DTPREL64MSB;
                  break;
                default:
-                 BFD_ASSERT (FALSE);
+                 BFD_ASSERT (false);
                  break;
                }
            }
@@ -3470,7 +3439,7 @@ set_fptr_entry (bfd *abfd, struct bfd_link_info *info,
 static bfd_vma
 set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
                  struct elfNN_ia64_dyn_sym_info *dyn_i,
-                 bfd_vma value, bfd_boolean is_plt)
+                 bfd_vma value, bool is_plt)
 {
   struct elfNN_ia64_link_hash_table *ia64_info;
   asection *pltoff_sec;
@@ -3496,8 +3465,7 @@ set_pltoff_entry (bfd *abfd, struct bfd_link_info *info,
       if (!is_plt
          && bfd_link_pic (info)
          && (!dyn_i->h
-             || (ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
-                 && !UNDEFWEAK_NO_DYNAMIC_RELOC (info, dyn_i->h))
+             || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
              || dyn_i->h->root.type != bfd_link_hash_undefweak))
        {
          unsigned int dyn_r_type;
@@ -3569,8 +3537,8 @@ elfNN_ia64_unwind_entry_compare (const void * a, const void * b)
 }
 
 /* Make sure we've got ourselves a nice fat __gp value.  */
-static bfd_boolean
-elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
+static bool
+elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bool final)
 {
   bfd_vma min_vma = (bfd_vma) -1, max_vma = 0;
   bfd_vma min_short_vma = min_vma, max_short_vma = 0;
@@ -3581,7 +3549,7 @@ elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   /* Find the min and max vma of all sections marked short.  Also collect
      min and max vma of any type, for use in selecting a nice gp.  */
@@ -3630,8 +3598,8 @@ elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
     }
 
   /* See if the user wants to force a value.  */
-  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
-                            FALSE, FALSE);
+  gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
+                            false, false);
 
   if (gp
       && (gp->root.type == bfd_link_hash_defined
@@ -3696,12 +3664,12 @@ elfNN_ia64_choose_gp (bfd *abfd, struct bfd_link_info *info, bfd_boolean final)
     {
       if (max_short_vma - min_short_vma >= 0x400000)
        {
-overflow:
+       overflow:
          _bfd_error_handler
            /* xgettext:c-format */
            (_("%pB: short data segment overflowed (%#" PRIx64 " >= 0x400000)"),
             abfd, (uint64_t) (max_short_vma - min_short_vma));
-         return FALSE;
+         return false;
        }
       else if ((gp_val > min_short_vma
                && gp_val - min_short_vma > 0x200000)
@@ -3710,16 +3678,16 @@ overflow:
        {
          _bfd_error_handler
            (_("%pB: __gp does not cover short data segment"), abfd);
-         return FALSE;
+         return false;
        }
     }
 
   _bfd_set_gp_value (abfd, gp_val);
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
 {
   struct elfNN_ia64_link_hash_table *ia64_info;
@@ -3727,7 +3695,7 @@ elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   /* Make sure we've got ourselves a nice fat __gp value.  */
   if (!bfd_link_relocatable (info))
@@ -3738,12 +3706,12 @@ elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
       /* We assume after gp is set, section size will only decrease. We
         need to adjust gp for it.  */
       _bfd_set_gp_value (abfd, 0);
-      if (! elfNN_ia64_choose_gp (abfd, info, TRUE))
-       return FALSE;
+      if (! elfNN_ia64_choose_gp (abfd, info, true))
+       return false;
       gp_val = _bfd_get_gp_value (abfd);
 
-      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", FALSE,
-                                FALSE, FALSE);
+      gp = elf_link_hash_lookup (elf_hash_table (info), "__gp", false,
+                                false, false);
       if (gp)
        {
          gp->root.type = bfd_link_hash_defined;
@@ -3765,13 +3733,13 @@ elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
          unwind_output_sec->contents
            = bfd_malloc (unwind_output_sec->size);
          if (unwind_output_sec->contents == NULL)
-           return FALSE;
+           return false;
        }
     }
 
   /* Invoke the regular ELF backend linker to do all the work.  */
   if (!bfd_elf_final_link (abfd, info))
-    return FALSE;
+    return false;
 
   if (unwind_output_sec)
     {
@@ -3784,13 +3752,13 @@ elfNN_ia64_final_link (bfd *abfd, struct bfd_link_info *info)
       if (! bfd_set_section_contents (abfd, unwind_output_sec,
                                      unwind_output_sec->contents, (bfd_vma) 0,
                                      unwind_output_sec->size))
-       return FALSE;
+       return false;
     }
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static int
 elfNN_ia64_relocate_section (bfd *output_bfd,
                             struct bfd_link_info *info,
                             bfd *input_bfd,
@@ -3805,13 +3773,13 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
   Elf_Internal_Rela *rel;
   Elf_Internal_Rela *relend;
   asection *srel;
-  bfd_boolean ret_val = TRUE;  /* for non-fatal errors */
+  bool ret_val = true; /* for non-fatal errors */
   bfd_vma gp_val;
 
   symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   /* Infect various flags from the input section to the output section.  */
   if (bfd_link_relocatable (info))
@@ -3826,7 +3794,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
     }
 
   gp_val = _bfd_get_gp_value (output_bfd);
-  srel = get_reloc_section (input_bfd, ia64_info, input_section, FALSE);
+  srel = get_reloc_section (input_bfd, ia64_info, input_section, false);
 
   rel = relocs;
   relend = relocs + input_section->reloc_count;
@@ -3842,8 +3810,8 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
       bfd_vma value;
       asection *sym_sec;
       bfd_byte *hit_addr;
-      bfd_boolean dynamic_symbol_p;
-      bfd_boolean undef_weak_ref;
+      bool dynamic_symbol_p;
+      bool undef_weak_ref;
 
       r_type = ELFNN_R_TYPE (rel->r_info);
       if (r_type > R_IA64_MAX_RELOC_CODE)
@@ -3852,16 +3820,22 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
          _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
                              input_bfd, (int) r_type);
          bfd_set_error (bfd_error_bad_value);
-         ret_val = FALSE;
+         ret_val = false;
          continue;
        }
 
       howto = ia64_elf_lookup_howto (r_type);
+      if (howto == NULL)
+       {
+         ret_val = false;
+         continue;
+       }
+
       r_symndx = ELFNN_R_SYM (rel->r_info);
       h = NULL;
       sym = NULL;
       sym_sec = NULL;
-      undef_weak_ref = FALSE;
+      undef_weak_ref = false;
 
       if (r_symndx < symtab_hdr->sh_info)
        {
@@ -3878,7 +3852,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
            {
              struct elfNN_ia64_local_hash_entry *loc_h;
 
-             loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, FALSE);
+             loc_h = get_local_sym_hash (ia64_info, input_bfd, rel, false);
              if (loc_h && ! loc_h->sec_merge_done)
                {
                  struct elfNN_ia64_dyn_sym_info *dynent;
@@ -3917,8 +3891,8 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        }
       else
        {
-         bfd_boolean unresolved_reloc;
-         bfd_boolean warned, ignored;
+         bool unresolved_reloc;
+         bool warned, ignored;
          struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
 
          RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
@@ -3927,7 +3901,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                                   unresolved_reloc, warned, ignored);
 
          if (h->root.type == bfd_link_hash_undefweak)
-           undef_weak_ref = TRUE;
+           undef_weak_ref = true;
          else if (warned || (ignored && bfd_link_executable (info)))
            continue;
        }
@@ -3958,7 +3932,6 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        case R_IA64_DIR64LSB:
          /* Install a dynamic relocation for this reloc.  */
          if ((dynamic_symbol_p || bfd_link_pic (info))
-             && !(h && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
              && r_symndx != STN_UNDEF
              && (input_section->flags & SEC_ALLOC) != 0)
            {
@@ -3982,7 +3955,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                     h ? h->root.root.string
                       : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
                                           sym_sec));
-                 ret_val = FALSE;
+                 ret_val = false;
                  continue;
 
                default:
@@ -4050,7 +4023,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                 h ? h->root.root.string
                   : bfd_elf_sym_name (input_bfd, symtab_hdr, sym,
                                       sym_sec));
-             ret_val = FALSE;
+             ret_val = false;
              continue;
            }
          value -= gp_val;
@@ -4060,7 +4033,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        case R_IA64_LTOFF22:
        case R_IA64_LTOFF22X:
        case R_IA64_LTOFF64I:
-         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
          value = set_got_entry (input_bfd, info, dyn_i, (h ? h->dynindx : -1),
                                 rel->r_addend, value, R_IA64_DIRNNLSB);
          value -= gp_val;
@@ -4071,8 +4044,8 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        case R_IA64_PLTOFF64I:
        case R_IA64_PLTOFF64MSB:
        case R_IA64_PLTOFF64LSB:
-         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
-         value = set_pltoff_entry (output_bfd, info, dyn_i, value, FALSE);
+         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
+         value = set_pltoff_entry (output_bfd, info, dyn_i, value, false);
          value -= gp_val;
          r = ia64_elf_install_value (hit_addr, value, r_type);
          break;
@@ -4082,7 +4055,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        case R_IA64_FPTR32LSB:
        case R_IA64_FPTR64MSB:
        case R_IA64_FPTR64LSB:
-         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+         dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
          if (dyn_i->want_fptr)
            {
              if (!undef_weak_ref)
@@ -4110,7 +4083,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                      _bfd_error_handler
                        (_("%pB: linking non-pic code in a position independent executable"),
                         input_bfd);
-                     ret_val = FALSE;
+                     ret_val = false;
                      continue;
                    }
                  dynindx = 0;
@@ -4151,7 +4124,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
          {
            long dynindx;
 
-           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
            if (dyn_i->want_fptr)
              {
                BFD_ASSERT (h == NULL || h->dynindx == -1);
@@ -4205,7 +4178,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
          /* We should have created a PLT entry for any dynamic symbol.  */
          dyn_i = NULL;
          if (h)
-           dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+           dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
 
          if (dyn_i && dyn_i->want_plt2)
            {
@@ -4259,7 +4232,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                                                      symtab_hdr,
                                                      sym,
                                                      sym_sec));
-             ret_val = FALSE;
+             ret_val = false;
              continue;
            }
          goto finish_pcrel;
@@ -4414,7 +4387,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
                got_r_type = R_IA64_DTPRELNNLSB;
                break;
              }
-           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, FALSE);
+           dyn_i = get_dyn_sym_info (ia64_info, h, input_bfd, rel, false);
            value = set_got_entry (input_bfd, info, dyn_i, dynindx, r_addend,
                                   value, got_r_type);
            value -= gp_val;
@@ -4438,7 +4411,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
             don't try to continue.  */
          (*info->callbacks->undefined_symbol)
            (info, "__gp", input_bfd, input_section, rel->r_offset, 1);
-         return FALSE;
+         return false;
 
        case bfd_reloc_notsupported:
          {
@@ -4452,7 +4425,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
            (*info->callbacks->warning) (info, _("unsupported reloc"),
                                         name, input_bfd,
                                         input_section, rel->r_offset);
-           ret_val = FALSE;
+           ret_val = false;
          }
          break;
 
@@ -4460,7 +4433,7 @@ elfNN_ia64_relocate_section (bfd *output_bfd,
        case bfd_reloc_outofrange:
        case bfd_reloc_overflow:
        default:
-missing_tls_sec:
+       missing_tls_sec:
          {
            const char *name;
 
@@ -4524,7 +4497,7 @@ missing_tls_sec:
                break;
              }
 
-           ret_val = FALSE;
+           ret_val = false;
          }
          break;
        }
@@ -4533,7 +4506,7 @@ missing_tls_sec:
   return ret_val;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
                                  struct bfd_link_info *info,
                                  struct elf_link_hash_entry *h,
@@ -4544,9 +4517,9 @@ elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
-  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, FALSE);
+  dyn_i = get_dyn_sym_info (ia64_info, h, NULL, NULL, false);
 
   /* Fill in the PLT data, if required.  */
   if (dyn_i && dyn_i->want_plt)
@@ -4571,7 +4544,7 @@ elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
       plt_addr = (plt_sec->output_section->vma
                  + plt_sec->output_offset
                  + dyn_i->plt_offset);
-      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, TRUE);
+      pltoff_addr = set_pltoff_entry (output_bfd, info, dyn_i, plt_addr, true);
 
       /* Initialize the FULL PLT entry, if needed.  */
       if (dyn_i->want_plt2)
@@ -4621,10 +4594,10 @@ elfNN_ia64_finish_dynamic_symbol (bfd *output_bfd,
       || h == ia64_info->root.hplt)
     sym->st_shndx = SHN_ABS;
 
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_finish_dynamic_sections (bfd *abfd,
                                    struct bfd_link_info *info)
 {
@@ -4633,7 +4606,7 @@ elfNN_ia64_finish_dynamic_sections (bfd *abfd,
 
   ia64_info = elfNN_ia64_hash_table (info);
   if (ia64_info == NULL)
-    return FALSE;
+    return false;
 
   dynobj = ia64_info->root.dynobj;
 
@@ -4701,44 +4674,47 @@ elfNN_ia64_finish_dynamic_sections (bfd *abfd,
        }
     }
 
-  return TRUE;
+  return true;
 }
 \f
 /* ELF file flag handling:  */
 
 /* Function to keep IA-64 specific file flags.  */
-static bfd_boolean
+static bool
 elfNN_ia64_set_private_flags (bfd *abfd, flagword flags)
 {
   BFD_ASSERT (!elf_flags_init (abfd)
              || elf_elfheader (abfd)->e_flags == flags);
 
   elf_elfheader (abfd)->e_flags = flags;
-  elf_flags_init (abfd) = TRUE;
-  return TRUE;
+  elf_flags_init (abfd) = true;
+  return true;
 }
 
 /* Merge backend specific data from an object file to the output
    object file when linking.  */
-static bfd_boolean
+
+static bool
 elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
 {
   bfd *obfd = info->output_bfd;
   flagword out_flags;
   flagword in_flags;
-  bfd_boolean ok = TRUE;
+  bool ok = true;
+
+  /* FIXME: What should be checked when linking shared libraries?  */
+  if ((ibfd->flags & DYNAMIC) != 0)
+    return true;
 
-  /* Don't even pretend to support mixed-format linking.  */
-  if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour
-      || bfd_get_flavour (obfd) != bfd_target_elf_flavour)
-    return FALSE;
+  if (!is_ia64_elf (ibfd) || !is_ia64_elf (obfd))
+    return true;
 
   in_flags  = elf_elfheader (ibfd)->e_flags;
   out_flags = elf_elfheader (obfd)->e_flags;
 
   if (! elf_flags_init (obfd))
     {
-      elf_flags_init (obfd) = TRUE;
+      elf_flags_init (obfd) = true;
       elf_elfheader (obfd)->e_flags = in_flags;
 
       if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
@@ -4748,12 +4724,12 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
                                    bfd_get_mach (ibfd));
        }
 
-      return TRUE;
+      return true;
     }
 
   /* Check flag compatibility.  */
   if (in_flags == out_flags)
-    return TRUE;
+    return true;
 
   /* Output has EF_IA_64_REDUCEDFP set only if all inputs have it set.  */
   if (!(in_flags & EF_IA_64_REDUCEDFP) && (out_flags & EF_IA_64_REDUCEDFP))
@@ -4766,7 +4742,7 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         ibfd);
 
       bfd_set_error (bfd_error_bad_value);
-      ok = FALSE;
+      ok = false;
     }
   if ((in_flags & EF_IA_64_BE) != (out_flags & EF_IA_64_BE))
     {
@@ -4775,7 +4751,7 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         ibfd);
 
       bfd_set_error (bfd_error_bad_value);
-      ok = FALSE;
+      ok = false;
     }
   if ((in_flags & EF_IA_64_ABI64) != (out_flags & EF_IA_64_ABI64))
     {
@@ -4784,7 +4760,7 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         ibfd);
 
       bfd_set_error (bfd_error_bad_value);
-      ok = FALSE;
+      ok = false;
     }
   if ((in_flags & EF_IA_64_CONS_GP) != (out_flags & EF_IA_64_CONS_GP))
     {
@@ -4793,7 +4769,7 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         ibfd);
 
       bfd_set_error (bfd_error_bad_value);
-      ok = FALSE;
+      ok = false;
     }
   if ((in_flags & EF_IA_64_NOFUNCDESC_CONS_GP)
       != (out_flags & EF_IA_64_NOFUNCDESC_CONS_GP))
@@ -4803,13 +4779,13 @@ elfNN_ia64_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
         ibfd);
 
       bfd_set_error (bfd_error_bad_value);
-      ok = FALSE;
+      ok = false;
     }
 
   return ok;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
 {
   FILE *file = (FILE *) ptr;
@@ -4828,7 +4804,7 @@ elfNN_ia64_print_private_bfd_data (bfd *abfd, void * ptr)
           (flags & EF_IA_64_ABI64) ? "ABI64" : "ABI32");
 
   _bfd_elf_print_private_bfd_data (abfd, ptr);
-  return TRUE;
+  return true;
 }
 
 static enum elf_reloc_type_class
@@ -4860,7 +4836,7 @@ static const struct bfd_elf_special_section elfNN_ia64_special_sections[] =
   { NULL,                   0,   0, 0,            0 }
 };
 
-static bfd_boolean
+static bool
 elfNN_ia64_object_p (bfd *abfd)
 {
   asection *sec;
@@ -4868,10 +4844,10 @@ elfNN_ia64_object_p (bfd *abfd)
   flagword flags;
   const char *name;
   char *unwi_name, *unw_name;
-  bfd_size_type amt;
+  size_t amt;
 
   if (abfd->flags & DYNAMIC)
-    return TRUE;
+    return true;
 
   /* Flags for fake group section.  */
   flags = (SEC_LINKER_CREATED | SEC_GROUP | SEC_LINK_ONCE
@@ -4884,14 +4860,14 @@ elfNN_ia64_object_p (bfd *abfd)
       if (elf_sec_group (sec) == NULL
          && ((sec->flags & (SEC_LINK_ONCE | SEC_CODE | SEC_GROUP))
              == (SEC_LINK_ONCE | SEC_CODE))
-         && CONST_STRNEQ (sec->name, ".gnu.linkonce.t."))
+         && startswith (sec->name, ".gnu.linkonce.t."))
        {
          name = sec->name + 16;
 
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unwi.");
          unwi_name = bfd_alloc (abfd, amt);
          if (!unwi_name)
-           return FALSE;
+           return false;
 
          strcpy (stpcpy (unwi_name, ".gnu.linkonce.ia64unwi."), name);
          unwi = bfd_get_section_by_name (abfd, unwi_name);
@@ -4899,7 +4875,7 @@ elfNN_ia64_object_p (bfd *abfd)
          amt = strlen (name) + sizeof (".gnu.linkonce.ia64unw.");
          unw_name = bfd_alloc (abfd, amt);
          if (!unw_name)
-           return FALSE;
+           return false;
 
          strcpy (stpcpy (unw_name, ".gnu.linkonce.ia64unw."), name);
          unw = bfd_get_section_by_name (abfd, unw_name);
@@ -4909,7 +4885,7 @@ elfNN_ia64_object_p (bfd *abfd)
          group = bfd_make_section_anyway_with_flags (abfd, name,
                                                      flags);
          if (group == NULL)
-           return FALSE;
+           return false;
 
          /* Move the fake group section to the beginning.  */
          bfd_section_list_remove (abfd, group);
@@ -4950,36 +4926,40 @@ elfNN_ia64_object_p (bfd *abfd)
          elf_section_data (group)->this_hdr.sh_type = SHT_GROUP;
        }
     }
-  return TRUE;
+  return true;
 }
 
-static bfd_boolean
+static bool
 elfNN_ia64_hpux_vec (const bfd_target *vec)
 {
   extern const bfd_target ia64_elfNN_hpux_be_vec;
   return (vec == &ia64_elfNN_hpux_be_vec);
 }
 
-static void
-elfNN_hpux_post_process_headers (bfd *abfd,
-                                struct bfd_link_info *info ATTRIBUTE_UNUSED)
+static bool
+elfNN_hpux_init_file_header (bfd *abfd, struct bfd_link_info *info)
 {
-  Elf_Internal_Ehdr *i_ehdrp = elf_elfheader (abfd);
+  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;
 }
 
-static bfd_boolean
+static bool
 elfNN_hpux_backend_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
                                             asection *sec, int *retval)
 {
   if (bfd_is_com_section (sec))
     {
       *retval = SHN_IA_64_ANSI_COMMON;
-      return TRUE;
+      return true;
     }
-  return FALSE;
+  return false;
 }
 
 static void
@@ -4997,6 +4977,11 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
       break;
     }
 }
+
+static void
+ignore_errors (const char *fmt ATTRIBUTE_UNUSED, ...)
+{
+}
 \f
 #define TARGET_LITTLE_SYM              ia64_elfNN_le_vec
 #define TARGET_LITTLE_NAME             "elfNN-ia64-little"
@@ -5024,8 +5009,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
        elfNN_ia64_additional_program_headers
 #define elf_backend_modify_segment_map \
        elfNN_ia64_modify_segment_map
-#define elf_backend_modify_program_headers \
-       elfNN_ia64_modify_program_headers
+#define elf_backend_modify_headers \
+       elfNN_ia64_modify_headers
 #define elf_info_to_howto \
        elfNN_ia64_info_to_howto
 
@@ -5094,7 +5079,7 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
    We don't want to flood users with so many error messages. We turn
    off the warning for now. It will be turned on later when the Intel
    compiler is fixed.   */
-#define elf_backend_link_order_error_handler NULL
+#define elf_backend_link_order_error_handler ignore_errors
 
 #include "elfNN-target.h"
 
@@ -5109,8 +5094,8 @@ elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
 
 /* These are HP-UX specific functions.  */
 
-#undef  elf_backend_post_process_headers
-#define elf_backend_post_process_headers elfNN_hpux_post_process_headers
+#undef  elf_backend_init_file_header
+#define elf_backend_init_file_header elfNN_hpux_init_file_header
 
 #undef  elf_backend_section_from_bfd_section
 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section