2004-02-26 H.J. Lu <hongjiu.lu@intel.com>
[deliverable/binutils-gdb.git] / bfd / elfxx-ia64.c
index f98e4ee188d10f1c8bf241b8249a117ea4930d88..878511bb828c3f14baadb4e89ea52faa09014a39 100644 (file)
@@ -24,6 +24,8 @@
 #include "elf-bfd.h"
 #include "opcode/ia64.h"
 #include "elf/ia64.h"
+#include "objalloc.h"
+#include "hashtab.h"
 
 /* THE RULES for all the stuff the linker creates --
 
@@ -51,7 +53,7 @@
                descriptor for a MIN_PLT entry, and requires one IPLT reloc.
 
   MIN_PLT      Created by PLTOFF entries against dynamic symbols.  This
-               does not reqire dynamic relocations.  */
+               does not require dynamic relocations.  */
 
 #define NELEMS(a)      ((int) (sizeof (a) / sizeof ((a)[0])))
 
@@ -79,7 +81,7 @@ struct elfNN_ia64_dyn_sym_info
   bfd_vma dtpmod_offset;
   bfd_vma dtprel_offset;
 
-  /* The symbol table entry, if any, that this was derrived from.  */
+  /* The symbol table entry, if any, that this was derived from.  */
   struct elf_link_hash_entry *h;
 
   /* Used to count non-got, non-plt relocations for delayed sizing
@@ -90,6 +92,9 @@ struct elfNN_ia64_dyn_sym_info
     asection *srel;
     int type;
     int count;
+
+    /* Is this reloc against readonly section? */
+    bfd_boolean reltext;
   } *reloc_entries;
 
   /* TRUE when the section contents have been updated.  */
@@ -115,7 +120,8 @@ struct elfNN_ia64_dyn_sym_info
 
 struct elfNN_ia64_local_hash_entry
 {
-  struct bfd_hash_entry root;
+  int id;
+  unsigned int r_sym;
   struct elfNN_ia64_dyn_sym_info *info;
 
   /* TRUE if this hash entry's addends was translated for
@@ -123,12 +129,6 @@ struct elfNN_ia64_local_hash_entry
   unsigned sec_merge_done : 1;
 };
 
-struct elfNN_ia64_local_hash_table
-{
-  struct bfd_hash_table root;
-  /* No additional fields for now.  */
-};
-
 struct elfNN_ia64_link_hash_entry
 {
   struct elf_link_hash_entry root;
@@ -153,7 +153,8 @@ struct elfNN_ia64_link_hash_table
   unsigned self_dtpmod_done : 1;/* has self DTPMOD entry been finished? */
   bfd_vma self_dtpmod_offset;  /* .got offset to self DTPMOD entry */
 
-  struct elfNN_ia64_local_hash_table loc_hash_table;
+  htab_t loc_hash_table;
+  void *loc_hash_memory;
 };
 
 struct elfNN_ia64_allocate_data
@@ -196,34 +197,30 @@ static bfd_boolean elfNN_ia64_add_symbol_hook
 static int elfNN_ia64_additional_program_headers
   PARAMS ((bfd *abfd));
 static bfd_boolean elfNN_ia64_modify_segment_map
-  PARAMS ((bfd *));
+  PARAMS ((bfd *, struct bfd_link_info *));
 static bfd_boolean elfNN_ia64_is_local_label_name
   PARAMS ((bfd *abfd, const char *name));
 static bfd_boolean elfNN_ia64_dynamic_symbol_p
-  PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info));
-static bfd_boolean elfNN_ia64_local_hash_table_init
-  PARAMS ((struct elfNN_ia64_local_hash_table *ht, bfd *abfd,
-          new_hash_entry_func new));
-static struct bfd_hash_entry *elfNN_ia64_new_loc_hash_entry
-  PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
-          const char *string));
+  PARAMS ((struct elf_link_hash_entry *h, struct bfd_link_info *info, int));
 static struct bfd_hash_entry *elfNN_ia64_new_elf_hash_entry
   PARAMS ((struct bfd_hash_entry *entry, struct bfd_hash_table *table,
           const char *string));
 static void elfNN_ia64_hash_copy_indirect
-  PARAMS ((struct elf_backend_data *, struct elf_link_hash_entry *,
+  PARAMS ((const struct elf_backend_data *, struct elf_link_hash_entry *,
           struct elf_link_hash_entry *));
 static void elfNN_ia64_hash_hide_symbol
   PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, bfd_boolean));
+static hashval_t elfNN_ia64_local_htab_hash PARAMS ((const void *));
+static int elfNN_ia64_local_htab_eq PARAMS ((const void *ptr1,
+                                            const void *ptr2));
 static struct bfd_link_hash_table *elfNN_ia64_hash_table_create
   PARAMS ((bfd *abfd));
-static struct elfNN_ia64_local_hash_entry *elfNN_ia64_local_hash_lookup
-  PARAMS ((struct elfNN_ia64_local_hash_table *table, const char *string,
-          bfd_boolean create, bfd_boolean copy));
+static void elfNN_ia64_hash_table_free
+  PARAMS ((struct bfd_link_hash_table *hash));
 static bfd_boolean elfNN_ia64_global_dyn_sym_thunk
   PARAMS ((struct bfd_hash_entry *, PTR));
-static bfd_boolean elfNN_ia64_local_dyn_sym_thunk
-  PARAMS ((struct bfd_hash_entry *, PTR));
+static int elfNN_ia64_local_dyn_sym_thunk
+  PARAMS ((void **, PTR));
 static void elfNN_ia64_dyn_sym_traverse
   PARAMS ((struct elfNN_ia64_link_hash_table *ia64_info,
           bfd_boolean (*func) (struct elfNN_ia64_dyn_sym_info *, PTR),
@@ -249,9 +246,6 @@ static asection *get_pltoff
 static asection *get_reloc_section
   PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
           asection *sec, bfd_boolean create));
-static bfd_boolean count_dyn_reloc
-  PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
-          asection *srel, int type));
 static bfd_boolean elfNN_ia64_check_relocs
   PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
           const Elf_Internal_Rela *relocs));
@@ -446,21 +440,21 @@ static reloc_howto_type ia64_howto_table[] =
     IA64_HOWTO (R_IA64_TPREL14,            "TPREL14",     0, FALSE, FALSE),
     IA64_HOWTO (R_IA64_TPREL22,            "TPREL22",     0, FALSE, FALSE),
     IA64_HOWTO (R_IA64_TPREL64I,    "TPREL64I",           0, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  8, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  8, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_TPREL64MSB,  "TPREL64MSB",  4, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_TPREL64LSB,  "TPREL64LSB",  4, FALSE, FALSE),
     IA64_HOWTO (R_IA64_LTOFF_TPREL22, "LTOFF_TPREL22",  0, FALSE, FALSE),
 
-    IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB",  8, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB",  8, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPMOD64MSB, "TPREL64MSB",  4, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPMOD64LSB, "TPREL64LSB",  4, FALSE, FALSE),
     IA64_HOWTO (R_IA64_LTOFF_DTPMOD22, "LTOFF_DTPMOD22", 0, FALSE, FALSE),
 
     IA64_HOWTO (R_IA64_DTPREL14,    "DTPREL14",           0, FALSE, FALSE),
     IA64_HOWTO (R_IA64_DTPREL22,    "DTPREL22",           0, FALSE, FALSE),
     IA64_HOWTO (R_IA64_DTPREL64I,   "DTPREL64I",   0, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 4, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 4, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 8, FALSE, FALSE),
-    IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 8, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPREL32MSB, "DTPREL32MSB", 2, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPREL32LSB, "DTPREL32LSB", 2, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPREL64MSB, "DTPREL64MSB", 4, FALSE, FALSE),
+    IA64_HOWTO (R_IA64_DTPREL64LSB, "DTPREL64LSB", 4, FALSE, FALSE),
     IA64_HOWTO (R_IA64_LTOFF_DTPREL22, "LTOFF_DTPREL22", 0, FALSE, FALSE),
   };
 
@@ -656,6 +650,58 @@ static const bfd_byte oor_brl[16] =
   0x00, 0x00, 0x00, 0x00, 0x00, 0x00,  /*               brl.sptk.few tgt;; */
   0x00, 0x00, 0x00, 0xc0
 };
+
+static const bfd_byte oor_ip[48] =
+{
+  0x04, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MLX]        nop.m 0            */
+  0x00, 0x00, 0x00, 0x00, 0x00, 0xe0,  /*               movl r15=0         */
+  0x01, 0x00, 0x00, 0x60,
+  0x03, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MII]        nop.m 0            */
+  0x00, 0x01, 0x00, 0x60, 0x00, 0x00,  /*               mov r16=ip;;       */
+  0xf2, 0x80, 0x00, 0x80,              /*               add r16=r15,r16;;  */
+  0x11, 0x00, 0x00, 0x00, 0x01, 0x00,  /*  [MIB]        nop.m 0            */
+  0x60, 0x80, 0x04, 0x80, 0x03, 0x00,  /*               mov b6=r16         */
+  0x60, 0x00, 0x80, 0x00               /*               br b6;;            */
+};
+
+static size_t oor_branch_size = sizeof (oor_brl);
+
+void
+bfd_elfNN_ia64_after_parse (int itanium)
+{
+  oor_branch_size = itanium ? sizeof (oor_ip) : sizeof (oor_brl);
+}
+
+static void
+elfNN_ia64_relax_brl (bfd *abfd, bfd_byte *contents, bfd_vma off)
+{
+  int template;
+  bfd_byte *hit_addr;
+  bfd_vma t0, t1, i0, i1, i2;
+
+  hit_addr = (bfd_byte *) (contents + off);
+  hit_addr -= (long) hit_addr & 0x3;
+  t0 = bfd_get_64 (abfd, hit_addr);
+  t1 = bfd_get_64 (abfd, hit_addr + 8);
+
+  /* Keep the instruction in slot 0. */
+  i0 = (t0 >> 5) & 0x1ffffffffffLL;
+  /* Use nop.b for slot 1. */
+  i1 = 0x4000000000LL;
+  /* For slot 2, turn brl into br by masking out bit 40.  */
+  i2 = (t1 >> 23) & 0x0ffffffffffLL;
+
+  /* Turn a MLX bundle into a MBB bundle with the same stop-bit
+     variety.  */
+  template = 0x12;
+  if ((t0 & 0x1fLL) == 5)
+    template += 1;
+  t0 = (i1 << 46) | (i0 << 5) | template;
+  t1 = (i2 << 23) | (i1 >> 18);
+
+  bfd_put_64 (abfd, t0, hit_addr);
+  bfd_put_64 (abfd, t1, hit_addr + 8);
+}
 \f
 /* These functions do relaxation for IA-64 ELF.  */
 
@@ -691,14 +737,14 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
   *again = FALSE;
 
   /* Don't even try to relax for non-ELF outputs.  */
-  if (link_info->hash->creator->flavour != bfd_target_elf_flavour)
+  if (!is_elf_hash_table (link_info->hash))
     return FALSE;
 
   /* Nothing to do if there are no relocations or there is no need for
      the relax finalize pass.  */
   if ((sec->flags & SEC_RELOC) == 0
       || sec->reloc_count == 0
-      || (link_info->relax_finalizing
+      || (!link_info->need_relax_finalize
          && sec->need_finalize_relax == 0))
     return TRUE;
 
@@ -749,14 +795,31 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
        case R_IA64_PCREL21BI:
        case R_IA64_PCREL21M:
        case R_IA64_PCREL21F:
-         if (link_info->relax_finalizing)
+         /* In the finalize pass, all br relaxations are done. We can
+            skip it. */
+         if (!link_info->need_relax_finalize)
            continue;
          is_branch = TRUE;
          break;
 
+       case R_IA64_PCREL60B:
+         /* We can't optimize brl to br before the finalize pass since
+            br relaxations will increase the code size. Defer it to
+            the finalize pass.  */
+         if (link_info->need_relax_finalize)
+           {
+             sec->need_finalize_relax = 1;
+             continue;
+           }
+         is_branch = TRUE;
+         break;
+
        case R_IA64_LTOFF22X:
        case R_IA64_LDXMOV:
-         if (!link_info->relax_finalizing)
+         /* We can't relax ldx/mov before the finalize pass since
+            br relaxations will increase the code size. Defer it to
+            the finalize pass.  */
+         if (link_info->need_relax_finalize)
            {
              sec->need_finalize_relax = 1;
              continue;
@@ -788,7 +851,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
 
          isym = isymbuf + ELFNN_R_SYM (irel->r_info);
          if (isym->st_shndx == SHN_UNDEF)
-           continue;   /* We can't do anthing with undefined symbols.  */
+           continue;   /* We can't do anything with undefined symbols.  */
          else if (isym->st_shndx == SHN_ABS)
            tsec = bfd_abs_section_ptr;
          else if (isym->st_shndx == SHN_COMMON)
@@ -831,12 +894,12 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
            }
 
          /* Can't do anything else with dynamic symbols.  */
-         else if (elfNN_ia64_dynamic_symbol_p (h, link_info))
+         else if (elfNN_ia64_dynamic_symbol_p (h, link_info, r_type))
            continue;
 
          else
            {
-             /* We can't do anthing with undefined symbols.  */
+             /* We can't do anything with undefined symbols.  */
              if (h->root.type == bfd_link_hash_undefined
                  || h->root.type == bfd_link_hash_undefweak)
                continue;
@@ -860,6 +923,8 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
 
       if (is_branch)
        {
+         bfd_signed_vma offset;
+
          reladdr = (sec->output_section->vma
                     + sec->output_offset
                     + roff) & (bfd_vma) -4;
@@ -867,6 +932,25 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
          /* If the branch is in range, no need to do anything.  */
          if ((bfd_signed_vma) (symaddr - reladdr) >= -0x1000000
              && (bfd_signed_vma) (symaddr - reladdr) <= 0x0FFFFF0)
+           {
+             /* If the 60-bit branch is in 21-bit range, optimize it. */
+             if (r_type == R_IA64_PCREL60B)
+               {
+                 elfNN_ia64_relax_brl (abfd, contents, roff);
+
+                 irel->r_info
+                   = ELF64_R_INFO (ELF64_R_SYM (irel->r_info),
+                                   R_IA64_PCREL21B);
+
+                 /* If the original relocation offset points to slot
+                    1, change it to slot 2.  */
+                 if ((irel->r_offset & 3) == 1)
+                   irel->r_offset += 1;
+               }
+
+             continue;
+           }
+         else if (r_type == R_IA64_PCREL60B)
            continue;
 
          /* If the branch and target are in the same section, you've
@@ -891,12 +975,17 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
              if (tsec == ia64_info->plt_sec)
                size = sizeof (plt_full_entry);
              else
-               {
-                 size = sizeof (oor_brl);
-               }
+               size = oor_branch_size;
 
              /* Resize the current section to make room for the new branch. */
              trampoff = (sec->_cooked_size + 15) & (bfd_vma) -16;
+
+             /* If trampoline is out of range, there is nothing we
+                can do.  */
+             offset = trampoff - (roff & (bfd_vma) -4);
+             if (offset < -0x1000000 || offset > 0x0FFFFF0)
+               continue;
+
              amt = trampoff + size;
              contents = (bfd_byte *) bfd_realloc (contents, amt);
              if (contents == NULL)
@@ -914,10 +1003,22 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
                }
              else
                {
-                 memcpy (contents + trampoff, oor_brl, size);
-                 irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
-                                              R_IA64_PCREL60B);
-                 irel->r_offset = trampoff + 2;
+                 if (size == sizeof (oor_ip))
+                   {
+                     memcpy (contents + trampoff, oor_ip, size);
+                     irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+                                                  R_IA64_PCREL64I);
+                     irel->r_addend -= 16;
+                     irel->r_offset = trampoff + 2;
+                   }
+                 else
+                   {
+                     memcpy (contents + trampoff, oor_brl, size);
+                     irel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (irel->r_info),
+                                                  R_IA64_PCREL60B);
+                     irel->r_offset = trampoff + 2;
+                   }
+
                }
 
              /* Record the fixup so we don't do it again this section.  */
@@ -931,14 +1032,18 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
            }
          else
            {
+             /* If trampoline is out of range, there is nothing we
+                can do.  */
+             offset = f->trampoff - (roff & (bfd_vma) -4);
+             if (offset < -0x1000000 || offset > 0x0FFFFF0)
+               continue;
+
              /* Nop out the reloc, since we're finalizing things here.  */
              irel->r_info = ELFNN_R_INFO (0, R_IA64_NONE);
            }
 
-         /* Fix up the existing branch to hit the trampoline.  Hope like
-            hell this doesn't overflow too.  */
-         if (elfNN_ia64_install_value (abfd, contents + roff,
-                                       f->trampoff - (roff & (bfd_vma) -4),
+         /* Fix up the existing branch to hit the trampoline.  */
+         if (elfNN_ia64_install_value (abfd, contents + roff, offset,
                                        r_type) != bfd_reloc_ok)
            goto error_return;
 
@@ -1047,7 +1152,7 @@ elfNN_ia64_relax_section (abfd, sec, link_info, again)
       /* ??? Resize .rela.got too.  */
     }
 
-  if (link_info->relax_finalizing)
+  if (!link_info->need_relax_finalize)
     sec->need_finalize_relax = 0;
 
   *again = changed_contents || changed_relocs;
@@ -1379,8 +1484,9 @@ elfNN_ia64_additional_program_headers (abfd)
 }
 
 static bfd_boolean
-elfNN_ia64_modify_segment_map (abfd)
+elfNN_ia64_modify_segment_map (abfd, info)
      bfd *abfd;
+     struct bfd_link_info *info ATTRIBUTE_UNUSED;
 {
   struct elf_segment_map *m, **pm;
   Elf_Internal_Shdr *hdr;
@@ -1508,78 +1614,18 @@ elfNN_ia64_is_local_label_name (abfd, name)
 /* Should we do dynamic things to this symbol?  */
 
 static bfd_boolean
-elfNN_ia64_dynamic_symbol_p (h, info)
+elfNN_ia64_dynamic_symbol_p (h, info, r_type)
      struct elf_link_hash_entry *h;
      struct bfd_link_info *info;
+     int r_type;
 {
-  if (h == NULL)
-    return FALSE;
-
-  while (h->root.type == bfd_link_hash_indirect
-        || h->root.type == bfd_link_hash_warning)
-    h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-  if (h->dynindx == -1)
-    return FALSE;
-  switch (ELF_ST_VISIBILITY (h->other))
-    {
-    case STV_INTERNAL:
-    case STV_HIDDEN:
-      return FALSE;
-    default:
-      break;
-    }
+  bfd_boolean ignore_protected
+    = ((r_type & 0xf8) == 0x40         /* FPTR relocs */
+       || (r_type & 0xf8) == 0x50);    /* LTOFF_FPTR relocs */
 
-  if (h->root.type == bfd_link_hash_undefweak
-      || h->root.type == bfd_link_hash_defweak)
-    return TRUE;
-
-  /* If it isn't defined locally, then clearly it's dynamic.  */
-  if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
-    return TRUE;
-
-  /* Identify the cases where name binding rules say it resolves local.  */
-  return !(info->executable || info->symbolic);
+  return _bfd_elf_dynamic_symbol_p (h, info, ignore_protected);
 }
 \f
-static bfd_boolean
-elfNN_ia64_local_hash_table_init (ht, abfd, new)
-     struct elfNN_ia64_local_hash_table *ht;
-     bfd *abfd ATTRIBUTE_UNUSED;
-     new_hash_entry_func new;
-{
-  memset (ht, 0, sizeof (*ht));
-  return bfd_hash_table_init (&ht->root, new);
-}
-
-static struct bfd_hash_entry*
-elfNN_ia64_new_loc_hash_entry (entry, table, string)
-     struct bfd_hash_entry *entry;
-     struct bfd_hash_table *table;
-     const char *string;
-{
-  struct elfNN_ia64_local_hash_entry *ret;
-  ret = (struct elfNN_ia64_local_hash_entry *) entry;
-
-  /* Allocate the structure if it has not already been allocated by a
-     subclass.  */
-  if (!ret)
-    ret = bfd_hash_allocate (table, sizeof (*ret));
-
-  if (!ret)
-    return 0;
-
-  /* Initialize our local data.  All zeros, and definitely easier
-     than setting a handful of bit fields.  */
-  memset (ret, 0, sizeof (*ret));
-
-  /* Call the allocation method of the superclass.  */
-  ret = ((struct elfNN_ia64_local_hash_entry *)
-        bfd_hash_newfunc ((struct bfd_hash_entry *) ret, table, string));
-
-  return (struct bfd_hash_entry *) ret;
-}
-
 static struct bfd_hash_entry*
 elfNN_ia64_new_elf_hash_entry (entry, table, string)
      struct bfd_hash_entry *entry;
@@ -1611,7 +1657,7 @@ elfNN_ia64_new_elf_hash_entry (entry, table, string)
 
 static void
 elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
-     struct elf_backend_data *bed ATTRIBUTE_UNUSED;
+     const struct elf_backend_data *bed ATTRIBUTE_UNUSED;
      struct elf_link_hash_entry *xdir, *xind;
 {
   struct elfNN_ia64_link_hash_entry *dir, *ind;
@@ -1626,7 +1672,8 @@ elfNN_ia64_hash_copy_indirect (bed, xdir, xind)
     (ind->root.elf_link_hash_flags
      & (ELF_LINK_HASH_REF_DYNAMIC
         | ELF_LINK_HASH_REF_REGULAR
-        | ELF_LINK_HASH_REF_REGULAR_NONWEAK));
+        | ELF_LINK_HASH_REF_REGULAR_NONWEAK
+        | ELF_LINK_HASH_NEEDS_PLT));
 
   if (ind->root.root.type != bfd_link_hash_indirect)
     return;
@@ -1679,6 +1726,33 @@ elfNN_ia64_hash_hide_symbol (info, xh, force_local)
     }
 }
 
+/* Compute a hash of a local hash entry.  */
+
+static hashval_t
+elfNN_ia64_local_htab_hash (ptr)
+     const void *ptr;
+{
+  struct elfNN_ia64_local_hash_entry *entry
+    = (struct elfNN_ia64_local_hash_entry *) ptr;
+
+  return (((entry->id & 0xff) << 24) | ((entry->id & 0xff00) << 8))
+         ^ entry->r_sym ^ (entry->id >> 16);
+}
+
+/* Compare local hash entries.  */
+
+static int
+elfNN_ia64_local_htab_eq (ptr1, ptr2)
+     const void *ptr1, *ptr2;
+{
+  struct elfNN_ia64_local_hash_entry *entry1
+    = (struct elfNN_ia64_local_hash_entry *) ptr1;
+  struct elfNN_ia64_local_hash_entry *entry2
+    = (struct elfNN_ia64_local_hash_entry *) ptr2;
+
+  return entry1->id == entry2->id && entry1->r_sym == entry2->r_sym;
+}
+
 /* Create the derived linker hash table.  The IA-64 ELF port uses this
    derived hash table to keep information specific to the IA-64 ElF
    linker (without using static variables).  */
@@ -1700,8 +1774,10 @@ elfNN_ia64_hash_table_create (abfd)
       return 0;
     }
 
-  if (!elfNN_ia64_local_hash_table_init (&ret->loc_hash_table, abfd,
-                                        elfNN_ia64_new_loc_hash_entry))
+  ret->loc_hash_table = htab_try_create (1024, elfNN_ia64_local_htab_hash,
+                                        elfNN_ia64_local_htab_eq, NULL);
+  ret->loc_hash_memory = objalloc_create ();
+  if (!ret->loc_hash_table || !ret->loc_hash_memory)
     {
       free (ret);
       return 0;
@@ -1710,16 +1786,19 @@ elfNN_ia64_hash_table_create (abfd)
   return &ret->root.root;
 }
 
-/* Look up an entry in a Alpha ELF linker hash table.  */
+/* Destroy IA-64 linker hash table.  */
 
-static INLINE struct elfNN_ia64_local_hash_entry *
-elfNN_ia64_local_hash_lookup(table, string, create, copy)
-     struct elfNN_ia64_local_hash_table *table;
-     const char *string;
-     bfd_boolean create, copy;
+static void
+elfNN_ia64_hash_table_free (hash)
+     struct bfd_link_hash_table *hash;
 {
-  return ((struct elfNN_ia64_local_hash_entry *)
-         bfd_hash_lookup (&table->root, string, create, copy));
+  struct elfNN_ia64_link_hash_table *ia64_info
+    = (struct elfNN_ia64_link_hash_table *) hash;
+  if (ia64_info->loc_hash_table)
+    htab_delete (ia64_info->loc_hash_table);
+  if (ia64_info->loc_hash_memory)
+    objalloc_free ((struct objalloc *) ia64_info->loc_hash_memory);
+  _bfd_generic_link_hash_table_free (hash);
 }
 
 /* Traverse both local and global hash tables.  */
@@ -1751,20 +1830,20 @@ elfNN_ia64_global_dyn_sym_thunk (xentry, xdata)
 }
 
 static bfd_boolean
-elfNN_ia64_local_dyn_sym_thunk (xentry, xdata)
-     struct bfd_hash_entry *xentry;
+elfNN_ia64_local_dyn_sym_thunk (slot, xdata)
+     void **slot;
      PTR xdata;
 {
   struct elfNN_ia64_local_hash_entry *entry
-    = (struct elfNN_ia64_local_hash_entry *) xentry;
+    = (struct elfNN_ia64_local_hash_entry *) *slot;
   struct elfNN_ia64_dyn_sym_traverse_data *data
     = (struct elfNN_ia64_dyn_sym_traverse_data *) xdata;
   struct elfNN_ia64_dyn_sym_info *dyn_i;
 
   for (dyn_i = entry->info; dyn_i; dyn_i = dyn_i->next)
     if (! (*data->func) (dyn_i, data->data))
-      return FALSE;
-  return TRUE;
+      return 0;
+  return 1;
 }
 
 static void
@@ -1780,8 +1859,8 @@ elfNN_ia64_dyn_sym_traverse (ia64_info, func, data)
 
   elf_link_hash_traverse (&ia64_info->root,
                          elfNN_ia64_global_dyn_sym_thunk, &xdata);
-  bfd_hash_traverse (&ia64_info->loc_hash_table.root,
-                    elfNN_ia64_local_dyn_sym_thunk, &xdata);
+  htab_traverse (ia64_info->loc_hash_table,
+                elfNN_ia64_local_dyn_sym_thunk, &xdata);
 }
 \f
 static bfd_boolean
@@ -1803,6 +1882,8 @@ elfNN_ia64_create_dynamic_sections (abfd, info)
   {
     flagword flags = bfd_get_section_flags (abfd, ia64_info->got_sec);
     bfd_set_section_flags (abfd, ia64_info->got_sec, SEC_SMALL_DATA | flags);
+    /* The .got section is always aligned at 8 bytes.  */
+    bfd_set_section_alignment (abfd, ia64_info->got_sec, 3);
   }
 
   if (!get_pltoff (abfd, info, ia64_info))
@@ -1841,22 +1922,33 @@ get_local_sym_hash (ia64_info, abfd, rel, create)
      const Elf_Internal_Rela *rel;
      bfd_boolean create;
 {
-  struct elfNN_ia64_local_hash_entry *ret;
+  struct elfNN_ia64_local_hash_entry e, *ret;
   asection *sec = abfd->sections;
-  char addr_name [34];
+  hashval_t h = (((sec->id & 0xff) << 24) | ((sec->id & 0xff00) << 8))
+               ^ ELFNN_R_SYM (rel->r_info) ^ (sec->id >> 16);
+  void **slot;
 
-  BFD_ASSERT ((sizeof (sec->id)*2 + 1 + sizeof (unsigned long)*2 + 1) <= 34);
-  BFD_ASSERT (sec);
+  e.id = sec->id;
+  e.r_sym = ELFNN_R_SYM (rel->r_info);
+  slot = htab_find_slot_with_hash (ia64_info->loc_hash_table, &e, h,
+                                  create ? INSERT : NO_INSERT);
 
-  /* Construct a string for use in the elfNN_ia64_local_hash_table.
-     name describes what was once anonymous memory.  */
+  if (!slot)
+    return NULL;
 
-  sprintf (addr_name, "%x:%lx",
-          sec->id, (unsigned long) ELFNN_R_SYM (rel->r_info));
+  if (*slot)
+    return (struct elfNN_ia64_local_hash_entry *) *slot;
 
-  /* Collect the canonical entry data for this address.  */
-  ret = elfNN_ia64_local_hash_lookup (&ia64_info->loc_hash_table,
-                                     addr_name, create, create);
+  ret = (struct elfNN_ia64_local_hash_entry *)
+       objalloc_alloc ((struct objalloc *) ia64_info->loc_hash_memory,
+                       sizeof (struct elfNN_ia64_local_hash_entry));
+  if (ret)
+    {
+      memset (ret, 0, sizeof (*ret));
+      ret->id = sec->id;
+      ret->r_sym = ELFNN_R_SYM (rel->r_info);
+      *slot = ret;
+    }
   return ret;
 }
 
@@ -1929,6 +2021,10 @@ get_got (abfd, info, ia64_info)
       BFD_ASSERT (got);
       ia64_info->got_sec = got;
 
+      /* The .got section is always aligned at 8 bytes.  */
+      if (!bfd_set_section_alignment (abfd, got, 3))
+       return 0;
+
       flags = bfd_get_section_flags (abfd, got);
       bfd_set_section_flags (abfd, got, SEC_SMALL_DATA | flags);
     }
@@ -1937,7 +2033,7 @@ get_got (abfd, info, ia64_info)
 }
 
 /* Create function descriptor section (.opd).  This section is called .opd
-   because it contains "official prodecure descriptors".  The "official"
+   because it contains "official procedure descriptors".  The "official"
    refers to the fact that these descriptors are used when taking the address
    of a procedure, thus ensuring a unique address for each procedure.  */
 
@@ -1977,9 +2073,9 @@ get_fptr (abfd, info, ia64_info)
       if (info->pie)
        {
          asection *fptr_rel;
-         fptr_rel = bfd_make_section(abfd, ".rela.opd");
+         fptr_rel = bfd_make_section(dynobj, ".rela.opd");
          if (fptr_rel == NULL
-             || !bfd_set_section_flags (abfd, fptr_rel,
+             || !bfd_set_section_flags (dynobj, fptr_rel,
                                         (SEC_ALLOC | SEC_LOAD
                                          | SEC_HAS_CONTENTS
                                          | SEC_IN_MEMORY
@@ -2079,18 +2175,12 @@ get_reloc_section (abfd, ia64_info, sec, create)
        return NULL;
     }
 
-  if (sec->flags & SEC_READONLY)
-    ia64_info->reltext = 1;
-
   return srel;
 }
 
 static bfd_boolean
-count_dyn_reloc (abfd, dyn_i, srel, type)
-     bfd *abfd;
-     struct elfNN_ia64_dyn_sym_info *dyn_i;
-     asection *srel;
-     int type;
+count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
+                asection *srel, int type, bfd_boolean reltext)
 {
   struct elfNN_ia64_dyn_reloc_entry *rent;
 
@@ -2111,6 +2201,7 @@ count_dyn_reloc (abfd, dyn_i, srel, type)
       rent->count = 0;
       dyn_i->reloc_entries = rent;
     }
+  rent->reltext = reltext;
   rent->count++;
 
   return TRUE;
@@ -2180,7 +2271,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
         this may help reduce memory usage and processing time later.  */
       maybe_dynamic = FALSE;
       if (h && ((!info->executable
-                     && (!info->symbolic || info->allow_shlib_undefined))
+                && (!info->symbolic || info->unresolved_syms_in_shared_libs == RM_IGNORE))
                || ! (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
                || h->root.type == bfd_link_hash_defweak))
        maybe_dynamic = TRUE;
@@ -2395,7 +2486,8 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
              if (!srel)
                return FALSE;
            }
-         if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
+         if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
+                               (sec->flags & SEC_READONLY) != 0))
            return FALSE;
        }
     }
@@ -2415,7 +2507,7 @@ allocate_global_data_got (dyn_i, data)
 
   if ((dyn_i->want_got || dyn_i->want_gotx)
       && ! dyn_i->want_fptr
-      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
+      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
      {
        dyn_i->got_offset = x->ofs;
        x->ofs += 8;
@@ -2427,7 +2519,7 @@ allocate_global_data_got (dyn_i, data)
     }
   if (dyn_i->want_dtpmod)
     {
-      if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
+      if (elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
        {
          dyn_i->dtpmod_offset = x->ofs;
          x->ofs += 8;
@@ -2464,7 +2556,7 @@ allocate_global_fptr_got (dyn_i, data)
 
   if (dyn_i->want_got
       && dyn_i->want_fptr
-      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
+      && elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, R_IA64_FPTR64LSB))
     {
       dyn_i->got_offset = x->ofs;
       x->ofs += 8;
@@ -2482,7 +2574,7 @@ allocate_local_got (dyn_i, data)
   struct elfNN_ia64_allocate_data *x = (struct elfNN_ia64_allocate_data *)data;
 
   if ((dyn_i->want_got || dyn_i->want_gotx)
-      && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info))
+      && !elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info, 0))
     {
       dyn_i->got_offset = x->ofs;
       x->ofs += 8;
@@ -2576,7 +2668,7 @@ allocate_plt_entries (dyn_i, data)
          h = (struct elf_link_hash_entry *) h->root.u.i.link;
 
       /* ??? Versioned symbols seem to lose ELF_LINK_HASH_NEEDS_PLT.  */
-      if (elfNN_ia64_dynamic_symbol_p (h, x->info))
+      if (elfNN_ia64_dynamic_symbol_p (h, x->info, 0))
        {
          bfd_size_type offset = x->ofs;
          if (offset == 0)
@@ -2654,7 +2746,10 @@ allocate_dynrel_entries (dyn_i, data)
   bfd_boolean dynamic_symbol, shared, resolved_zero;
 
   ia64_info = elfNN_ia64_hash_table (x->info);
-  dynamic_symbol = elfNN_ia64_dynamic_symbol_p (dyn_i->h, x->info);
+
+  /* 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 = x->info->shared;
   resolved_zero = (dyn_i->h
                   && ELF_ST_VISIBILITY (dyn_i->h->other)
@@ -2699,6 +2794,8 @@ allocate_dynrel_entries (dyn_i, data)
        default:
          abort ();
        }
+      if (rent->reltext)
+       ia64_info->reltext = 1;
       rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
     }
 
@@ -2779,7 +2876,7 @@ elfNN_ia64_adjust_dynamic_symbol (info, h)
 
 static bfd_boolean
 elfNN_ia64_size_dynamic_sections (output_bfd, info)
-     bfd *output_bfd;
+     bfd *output_bfd ATTRIBUTE_UNUSED;
      struct bfd_link_info *info;
 {
   struct elfNN_ia64_allocate_data data;
@@ -2909,6 +3006,15 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info)
          if (strip)
            ia64_info->fptr_sec = NULL;
        }
+      else if (sec == ia64_info->rel_fptr_sec)
+       {
+         if (strip)
+           ia64_info->rel_fptr_sec = NULL;
+         else
+           /* We use the reloc_count field as a counter if we need to
+              copy relocs into the output file.  */
+           sec->reloc_count = 0;
+       }
       else if (sec == ia64_info->plt_sec)
        {
          if (strip)
@@ -3342,7 +3448,7 @@ set_got_entry (abfd, info, dyn_i, dynindx, addend, value, dyn_r_type)
                || ELF_ST_VISIBILITY (dyn_i->h->other) == STV_DEFAULT
                || dyn_i->h->root.type != bfd_link_hash_undefweak)
            && dyn_r_type != R_IA64_DTPREL64LSB)
-           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info)
+           || elfNN_ia64_dynamic_symbol_p (dyn_i->h, info, dyn_r_type)
           || (dynindx != -1 && dyn_r_type == R_IA64_FPTR64LSB))
          && (!dyn_i->want_ltoff_fptr
              || !info->pie
@@ -3526,12 +3632,10 @@ static bfd_vma
 elfNN_ia64_tprel_base (info)
      struct bfd_link_info *info;
 {
-  struct elf_link_tls_segment *tls_segment
-    = elf_hash_table (info)->tls_segment;
+  asection *tls_sec = elf_hash_table (info)->tls_sec;
 
-  BFD_ASSERT (tls_segment != NULL);
-  return (tls_segment->start
-         - align_power ((bfd_vma) 16, tls_segment->align));
+  BFD_ASSERT (tls_sec != NULL);
+  return tls_sec->vma - align_power ((bfd_vma) 16, tls_sec->alignment_power);
 }
 
 /* Return the base VMA address which should be subtracted from real addresses
@@ -3542,8 +3646,8 @@ static bfd_vma
 elfNN_ia64_dtprel_base (info)
      struct bfd_link_info *info;
 {
-  BFD_ASSERT (elf_hash_table (info)->tls_segment != NULL);
-  return elf_hash_table (info)->tls_segment->start;
+  BFD_ASSERT (elf_hash_table (info)->tls_sec != NULL);
+  return elf_hash_table (info)->tls_sec->vma;
 }
 
 /* Called through qsort to sort the .IA_64.unwind section during a
@@ -3807,7 +3911,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
       asection *sym_sec;
       bfd_byte *hit_addr;
       bfd_boolean dynamic_symbol_p;
-      bfd_boolean local_symbol_p;
       bfd_boolean undef_weak_ref;
 
       r_type = ELFNN_R_TYPE (rel->r_info);
@@ -3831,9 +3934,11 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
       if (r_symndx < symtab_hdr->sh_info)
        {
          /* Reloc against local symbol.  */
+         asection *msec;
          sym = local_syms + r_symndx;
          sym_sec = local_sections[r_symndx];
-         value = _bfd_elf_rela_local_sym (output_bfd, sym, sym_sec, rel);
+         msec = sym_sec;
+         value = _bfd_elf_rela_local_sym (output_bfd, sym, &msec, rel);
          if ((sym_sec->flags & SEC_MERGE)
              && ELF_ST_TYPE (sym->st_info) == STT_SECTION
              && sym_sec->sec_info_type == ELF_INFO_TYPE_MERGE)
@@ -3844,7 +3949,6 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
              if (loc_h && ! loc_h->sec_merge_done)
                {
                  struct elfNN_ia64_dyn_sym_info *dynent;
-                 asection *msec;
 
                  for (dynent = loc_h->info; dynent; dynent = dynent->next)
                    {
@@ -3868,62 +3972,24 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
        }
       else
        {
-         long indx;
+         bfd_boolean unresolved_reloc;
+         bfd_boolean warned;
 
-         /* Reloc against global symbol.  */
-         indx = r_symndx - symtab_hdr->sh_info;
-         h = elf_sym_hashes (input_bfd)[indx];
-         while (h->root.type == bfd_link_hash_indirect
-                || h->root.type == bfd_link_hash_warning)
-           h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
-         value = 0;
-         if (h->root.type == bfd_link_hash_defined
-             || h->root.type == bfd_link_hash_defweak)
-           {
-             sym_sec = h->root.u.def.section;
+         RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
+                                  r_symndx,
+                                  symtab_hdr, value, sym_sec,
+                                  unresolved_reloc, info,
+                                  warned);
 
-             /* Detect the cases that sym_sec->output_section is
-                expected to be NULL -- all cases in which the symbol
-                is defined in another shared module.  This includes
-                PLT relocs for which we've created a PLT entry and
-                other relocs for which we're prepared to create
-                dynamic relocations.  */
-             /* ??? Just accept it NULL and continue.  */
-
-             if (sym_sec->output_section != NULL)
-               {
-                 value = (h->root.u.def.value
-                          + sym_sec->output_section->vma
-                          + sym_sec->output_offset);
-               }
-           }
-         else if (h->root.type == bfd_link_hash_undefweak)
+         if (h->root.type == bfd_link_hash_undefweak)
            undef_weak_ref = TRUE;
-         else if (! info->executable
-                  && !info->no_undefined
-                  && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-           ;
-         else
-           {
-             if (! ((*info->callbacks->undefined_symbol)
-                    (info, h->root.root.string, input_bfd,
-                     input_section, rel->r_offset,
-                     (!info->shared || info->no_undefined
-                      || ELF_ST_VISIBILITY (h->other)))))
-               return FALSE;
-             continue;
-           }
+         else if (warned)
+           continue;
        }
 
       hit_addr = contents + rel->r_offset;
       value += rel->r_addend;
-      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info);
-      /* Is this symbol locally defined? A protected symbol is locallly
-        defined. But its function descriptor may not. Use it with
-        caution.  */
-      local_symbol_p = (! dynamic_symbol_p
-                       || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT);
+      dynamic_symbol_p = elfNN_ia64_dynamic_symbol_p (h, info, r_type);
 
       switch (r_type)
        {
@@ -3949,10 +4015,28 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
 
              BFD_ASSERT (srel != NULL);
 
+             switch (r_type)
+               {
+               case R_IA64_IMM14:
+               case R_IA64_IMM22:
+               case R_IA64_IMM64:
+                 /* ??? People shouldn't be doing non-pic code in
+                    shared libraries nor dynamic executables.  */
+                 (*_bfd_error_handler)
+                   (_("%s: non-pic code with imm relocation against dynamic symbol `%s'"),
+                    bfd_archive_filename (input_bfd),
+                    h->root.root.string);
+                 ret_val = FALSE;
+                 continue;
+
+               default:
+                 break;
+               }
+
              /* If we don't need dynamic symbol lookup, find a
                 matching RELATIVE relocation.  */
              dyn_r_type = r_type;
-             if (! local_symbol_p)
+             if (dynamic_symbol_p)
                {
                  dynindx = h->dynindx;
                  addend = rel->r_addend;
@@ -3976,17 +4060,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
                      break;
 
                    default:
-                     /* We can't represent this without a dynamic symbol.
-                        Adjust the relocation to be against an output
-                        section symbol, which are always present in the
-                        dynamic symbol table.  */
-                     /* ??? People shouldn't be doing non-pic code in
-                        shared libraries.  Hork.  */
-                     (*_bfd_error_handler)
-                       (_("%s: linking non-pic code in a shared library"),
-                        bfd_archive_filename (input_bfd));
-                     ret_val = FALSE;
-                     continue;
+                     break;
                    }
                  dynindx = 0;
                  addend = value;
@@ -4300,7 +4374,7 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
 
              /* If we don't need dynamic symbol lookup, install two
                 RELATIVE relocations.  */
-             if (local_symbol_p)
+             if (!dynamic_symbol_p)
                {
                  unsigned int dyn_r_type;
 
@@ -4548,7 +4622,7 @@ elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym)
 
       loc = ia64_info->rel_pltoff_sec->contents;
       loc += ((ia64_info->rel_pltoff_sec->reloc_count + index)
-             * sizeof (Elf64_External_Rela));
+             * sizeof (ElfNN_External_Rela));
       bfd_elfNN_swap_reloca_out (output_bfd, &outrel, loc);
     }
 
@@ -4798,6 +4872,13 @@ elfNN_ia64_reloc_type_class (rela)
     }
 }
 
+static struct bfd_elf_special_section const elfNN_ia64_special_sections[]=
+{
+  { ".sbss",  5, -1, SHT_NOBITS,   SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+  { ".sdata", 6, -1, SHT_PROGBITS, SHF_ALLOC + SHF_WRITE + SHF_IA_64_SHORT },
+  { NULL,     0,  0, 0,            0 }
+};
+
 static bfd_boolean
 elfNN_ia64_hpux_vec (const bfd_target *vec)
 {
@@ -4829,6 +4910,23 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
     }
   return FALSE;
 }
+
+static void
+elfNN_hpux_backend_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED,
+                                     asymbol *asym)
+{
+  elf_symbol_type *elfsym = (elf_symbol_type *) asym;;
+
+  switch (elfsym->internal_elf_sym.st_shndx)
+    {
+    case SHN_IA_64_ANSI_COMMON:
+      asym->section = bfd_com_section_ptr;
+      asym->value = elfsym->internal_elf_sym.st_size;
+      asym->flags &= ~BSF_GLOBAL;
+      break;
+    }
+}
+
 \f
 #define TARGET_LITTLE_SYM              bfd_elfNN_ia64_little_vec
 #define TARGET_LITTLE_NAME             "elfNN-ia64-little"
@@ -4867,6 +4965,8 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
 /* Stuff for the BFD linker: */
 #define bfd_elfNN_bfd_link_hash_table_create \
        elfNN_ia64_hash_table_create
+#define bfd_elfNN_bfd_link_hash_table_free \
+       elfNN_ia64_hash_table_free
 #define elf_backend_create_dynamic_sections \
        elfNN_ia64_create_dynamic_sections
 #define elf_backend_check_relocs \
@@ -4895,7 +4995,6 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
 #define elf_backend_want_plt_sym       0
 #define elf_backend_plt_alignment      5
 #define elf_backend_got_header_size    0
-#define elf_backend_plt_header_size    PLT_HEADER_SIZE
 #define elf_backend_want_got_plt       1
 #define elf_backend_may_use_rel_p      1
 #define elf_backend_may_use_rela_p     1
@@ -4905,6 +5004,7 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
 #define elf_backend_hide_symbol                elfNN_ia64_hash_hide_symbol
 #define elf_backend_reloc_type_class   elfNN_ia64_reloc_type_class
 #define elf_backend_rela_normal                1
+#define elf_backend_special_sections   elfNN_ia64_special_sections
 
 #include "elfNN-target.h"
 
@@ -4925,6 +5025,9 @@ elfNN_hpux_backend_section_from_bfd_section (abfd, sec, retval)
 #undef  elf_backend_section_from_bfd_section
 #define elf_backend_section_from_bfd_section elfNN_hpux_backend_section_from_bfd_section
 
+#undef elf_backend_symbol_processing
+#define elf_backend_symbol_processing elfNN_hpux_backend_symbol_processing
+
 #undef  elf_backend_want_p_paddr_set_to_zero
 #define elf_backend_want_p_paddr_set_to_zero 1
 
This page took 0.038773 seconds and 4 git commands to generate.