]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blobdiff - gas/config/tc-ia64.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-ia64.c
index dcaa416178b36562ae334477cd39d808c41fdd36..c64c0d5cce2b8d22b32845996a12ff85ad7a6dfe 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-ia64.c -- Assembler for the HP/Intel IA-64 architecture.
-   Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009   Free Software Foundation, Inc.
+   Copyright (C) 1998-2021 Free Software Foundation, Inc.
    Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
 
    This file is part of GAS, the GNU Assembler.
@@ -103,6 +102,9 @@ enum reloc_func
     FUNC_LT_DTP_RELATIVE,
     FUNC_LT_TP_RELATIVE,
     FUNC_IPLT_RELOC,
+#ifdef TE_VMS
+    FUNC_SLOTCOUNT_RELOC,
+#endif
   };
 
 enum reg_symbol
@@ -111,7 +113,8 @@ enum reg_symbol
     REG_FR     = (REG_GR + 128),
     REG_AR     = (REG_FR + 128),
     REG_CR     = (REG_AR + 128),
-    REG_P      = (REG_CR + 128),
+    REG_DAHR   = (REG_CR + 128),
+    REG_P      = (REG_DAHR + 8),
     REG_BR     = (REG_P  + 64),
     REG_IP     = (REG_BR + 8),
     REG_CFM,
@@ -130,6 +133,7 @@ enum reg_symbol
     IND_PKR,
     IND_PMC,
     IND_PMD,
+    IND_DAHR,
     IND_RR,
     /* The following pseudo-registers are used for unwind directives only:  */
     REG_PSP,
@@ -163,6 +167,11 @@ struct label_fix
   bfd_boolean dw2_mark_labels;
 };
 
+#ifdef TE_VMS
+/* An internally used relocation.  */
+#define DUMMY_RELOC_IA64_SLOTCOUNT     (BFD_RELOC_UNUSED + 1)
+#endif
+
 /* This is the endianness of the current section.  */
 extern int target_big_endian;
 
@@ -176,10 +185,10 @@ static void ia64_float_to_chars_littleendian (char *, LITTLENUM_TYPE *, int);
 
 static void (*ia64_float_to_chars) (char *, LITTLENUM_TYPE *, int);
 
-static struct hash_control *alias_hash;
-static struct hash_control *alias_name_hash;
-static struct hash_control *secalias_hash;
-static struct hash_control *secalias_name_hash;
+static htab_t alias_hash;
+static htab_t alias_name_hash;
+static htab_t secalias_hash;
+static htab_t secalias_name_hash;
 
 /* List of chars besides those in app.c:symbol_chars that can start an
    operand.  Used to prevent the scrubber eating vital white-space.  */
@@ -219,13 +228,13 @@ size_t md_longopts_size = sizeof (md_longopts);
 
 static struct
   {
-    struct hash_control *pseudo_hash;  /* pseudo opcode hash table */
-    struct hash_control *reg_hash;     /* register name hash table */
-    struct hash_control *dynreg_hash;  /* dynamic register hash table */
-    struct hash_control *const_hash;   /* constant hash table */
-    struct hash_control *entry_hash;    /* code entry hint hash table */
+    htab_t pseudo_hash;        /* pseudo opcode hash table */
+    htab_t reg_hash;   /* register name hash table */
+    htab_t dynreg_hash;        /* dynamic register hash table */
+    htab_t const_hash; /* constant hash table */
+    htab_t entry_hash;    /* code entry hint hash table */
 
-    /* If X_op is != O_absent, the registername for the instruction's
+    /* If X_op is != O_absent, the register name for the instruction's
        qualifying predicate.  If NULL, p0 is assumed for instructions
        that are predictable.  */
     expressionS qp;
@@ -293,7 +302,7 @@ static struct
        struct label_fix *tag_fixups;
        struct unw_rec_list *unwind_record;     /* Unwind directive.  */
        expressionS opnd[6];
-       char *src_file;
+       const char *src_file;
        unsigned int src_line;
        struct dwarf2_line_info debug_line;
       }
@@ -531,6 +540,7 @@ indirect_reg[] =
     { "pkr",   IND_PKR },
     { "pmc",   IND_PMC },
     { "pmd",   IND_PMD },
+    { "dahr",  IND_DAHR },
     { "rr",    IND_RR },
   };
 
@@ -575,6 +585,9 @@ pseudo_func[] =
     { NULL, 0, { 0 } },        /* placeholder for FUNC_LT_DTP_RELATIVE */
     { NULL, 0, { 0 } },        /* placeholder for FUNC_LT_TP_RELATIVE */
     { "iplt",  PSEUDO_FUNC_RELOC, { 0 } },
+#ifdef TE_VMS
+    { "slotcount", PSEUDO_FUNC_RELOC, { 0 } },
+#endif
 
     /* mbtype4 constants:  */
     { "alt",   PSEUDO_FUNC_CONST, { 0xa } },
@@ -598,12 +611,18 @@ pseudo_func[] =
 
     /* hint constants: */
     { "pause", PSEUDO_FUNC_CONST, { 0x0 } },
+    { "priority", PSEUDO_FUNC_CONST, { 0x1 } },
+
+    /* tf constants: */
+    { "clz",   PSEUDO_FUNC_CONST, {  32 } },
+    { "mpy",   PSEUDO_FUNC_CONST, {  33 } },
+    { "datahints",     PSEUDO_FUNC_CONST, {  34 } },
 
     /* unwind-related constants:  */
     { "svr4",  PSEUDO_FUNC_CONST,      { ELFOSABI_NONE } },
     { "hpux",  PSEUDO_FUNC_CONST,      { ELFOSABI_HPUX } },
     { "nt",    PSEUDO_FUNC_CONST,      { 2 } },                /* conflicts w/ELFOSABI_NETBSD */
-    { "linux", PSEUDO_FUNC_CONST,      { ELFOSABI_LINUX } },
+    { "linux", PSEUDO_FUNC_CONST,      { ELFOSABI_GNU } },
     { "freebsd", PSEUDO_FUNC_CONST,    { ELFOSABI_FREEBSD } },
     { "openvms", PSEUDO_FUNC_CONST,    { ELFOSABI_OPENVMS } },
     { "nsk",   PSEUDO_FUNC_CONST,      { ELFOSABI_NSK } },
@@ -653,7 +672,7 @@ static struct rsrc {
   int insn_srlz;                    /* current insn serialization state */
   int data_srlz;                    /* current data serialization state */
   int qp_regno;                     /* qualifying predicate for this usage */
-  char *file;                       /* what file marked this dependency */
+  const char *file;                       /* what file marked this dependency */
   unsigned int line;                /* what line marked this dependency */
   struct mem_offset mem_offset;     /* optional memory offset hint */
   enum { CMP_NONE, CMP_OR, CMP_AND } cmp_type; /* OR or AND compare? */
@@ -810,7 +829,7 @@ ar_is_only_in_integer_unit (int reg)
   return reg >= 64 && reg <= 111;
 }
 
-/* Determine if application register REGNUM resides only in the memory 
+/* Determine if application register REGNUM resides only in the memory
    unit (as opposed to the integer unit).  */
 static int
 ar_is_only_in_memory_unit (int reg)
@@ -837,7 +856,7 @@ set_section (char *name)
 /* Map 's' to SHF_IA_64_SHORT.  */
 
 bfd_vma
-ia64_elf_section_letter (int letter, char **ptr_msg)
+ia64_elf_section_letter (int letter, const char **ptr_msg)
 {
   if (letter == 's')
     return SHF_IA_64_SHORT;
@@ -850,7 +869,7 @@ ia64_elf_section_letter (int letter, char **ptr_msg)
     return SHF_IA_64_VMS_GLOBAL;
 #endif
 
-  *ptr_msg = _("Bad .section directive: want a,o,s,w,x,M,S,G,T in string");
+  *ptr_msg = _("bad .section directive: want a,o,s,w,x,M,S,G,T in string");
   return -1;
 }
 
@@ -1006,28 +1025,153 @@ ia64_flush_insns (void)
     as_bad (_("qualifying predicate not followed by instruction"));
 }
 
-static void
-ia64_do_align (int nbytes)
-{
-  char *saved_input_line_pointer = input_line_pointer;
-
-  input_line_pointer = "";
-  s_align_bytes (nbytes);
-  input_line_pointer = saved_input_line_pointer;
-}
-
 void
 ia64_cons_align (int nbytes)
 {
   if (md.auto_align)
     {
-      char *saved_input_line_pointer = input_line_pointer;
-      input_line_pointer = "";
-      s_align_bytes (nbytes);
-      input_line_pointer = saved_input_line_pointer;
+      int log;
+      for (log = 0; (nbytes & 1) != 1; nbytes >>= 1)
+       log++;
+
+      do_align (log, NULL, 0, 0);
+    }
+}
+
+#ifdef TE_VMS
+
+/* .vms_common section, symbol, size, alignment  */
+
+static void
+obj_elf_vms_common (int ignore ATTRIBUTE_UNUSED)
+{
+  const char *sec_name;
+  char *sym_name;
+  char c;
+  offsetT size;
+  offsetT cur_size;
+  offsetT temp;
+  symbolS *symbolP;
+  segT current_seg = now_seg;
+  subsegT current_subseg = now_subseg;
+  offsetT log_align;
+
+  /* Section name.  */
+  sec_name = obj_elf_section_name ();
+  if (sec_name == NULL)
+    return;
+
+  /* Symbol name.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  else
+    {
+      as_bad (_("expected ',' after section name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  c = get_symbol_name (&sym_name);
+
+  if (input_line_pointer == sym_name)
+    {
+      (void) restore_line_pointer (c);
+      as_bad (_("expected symbol name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  symbolP = symbol_find_or_make (sym_name);
+  (void) restore_line_pointer (c);
+
+  if ((S_IS_DEFINED (symbolP) || symbol_equated_p (symbolP))
+      && !S_IS_COMMON (symbolP))
+    {
+      as_bad (_("Ignoring attempt to re-define symbol"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  /* Symbol size.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
+    }
+  else
+    {
+      as_bad (_("expected ',' after symbol name"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  temp = get_absolute_expression ();
+  size = temp;
+  size &= ((offsetT) 2 << (stdoutput->arch_info->bits_per_address - 1)) - 1;
+  if (temp != size)
+    {
+      as_warn (_("size (%ld) out of range, ignored"), (long) temp);
+      ignore_rest_of_line ();
+      return;
+    }
+
+  /* Alignment.  */
+  SKIP_WHITESPACE ();
+  if (*input_line_pointer == ',')
+    {
+      input_line_pointer++;
+      SKIP_WHITESPACE ();
     }
+  else
+    {
+      as_bad (_("expected ',' after symbol size"));
+      ignore_rest_of_line ();
+      return;
+    }
+
+  log_align = get_absolute_expression ();
+
+  demand_empty_rest_of_line ();
+
+  obj_elf_change_section
+    (sec_name, SHT_NOBITS,
+     SHF_ALLOC | SHF_WRITE | SHF_IA_64_VMS_OVERLAID | SHF_IA_64_VMS_GLOBAL,
+     0, NULL, 1, 0);
+
+  S_SET_VALUE (symbolP, 0);
+  S_SET_SIZE (symbolP, size);
+  S_SET_EXTERNAL (symbolP);
+  S_SET_SEGMENT (symbolP, now_seg);
+
+  symbol_get_bfdsym (symbolP)->flags |= BSF_OBJECT;
+
+  record_alignment (now_seg, log_align);
+
+  cur_size = bfd_section_size (now_seg);
+  if ((int) size > cur_size)
+    {
+      char *pfrag
+        = frag_var (rs_fill, 1, 1, (relax_substateT)0, NULL,
+                    (valueT)size - (valueT)cur_size, NULL);
+      *pfrag = 0;
+      bfd_set_section_size (now_seg, size);
+    }
+
+  /* Switch back to current segment.  */
+  subseg_set (current_seg, current_subseg);
+
+#ifdef md_elf_section_change_hook
+  md_elf_section_change_hook ();
+#endif
 }
 
+#endif /* TE_VMS */
+
 /* Output COUNT bytes to a memory location.  */
 static char *vbyte_mem_ptr = NULL;
 
@@ -1597,7 +1741,7 @@ static unw_rec_list *
 alloc_record (unw_record_type t)
 {
   unw_rec_list *ptr;
-  ptr = xmalloc (sizeof (*ptr));
+  ptr = XNEW (unw_rec_list);
   memset (ptr, 0, sizeof (*ptr));
   ptr->slot_number = SLOT_NUM_NOT_SET;
   ptr->r.type = t;
@@ -2506,8 +2650,7 @@ set_imask (unw_rec_list *region,
   if (!imask)
     {
       imask_size = (region->r.record.r.rlen * 2 + 7) / 8 + 1;
-      imask = xmalloc (imask_size);
-      memset (imask, 0, imask_size);
+      imask = XCNEWVEC (unsigned char, imask_size);
 
       region->r.record.r.imask_size = imask_size;
       region->r.record.r.mask.i = imask;
@@ -2595,6 +2738,7 @@ slot_index (unsigned long slot_addr,
                as_fatal (_("Only constant offsets are supported"));
                break;
              }
+           /* Fall through.  */
          case rs_fill:
            s_index += 3 * (first_frag->fr_offset >> 4);
            break;
@@ -2657,7 +2801,7 @@ fixup_unw_records (unw_rec_list *list, int before_relax)
   for (ptr = list; ptr; ptr = ptr->next)
     {
       if (ptr->slot_number == SLOT_NUM_NOT_SET)
-       as_bad (_(" Insn slot not set in unwind record."));
+       as_bad (_("Insn slot not set in unwind record."));
       t = slot_index (ptr->slot_number, ptr->slot_frag,
                      first_addr, first_frag, before_relax);
       switch (ptr->r.type)
@@ -2823,7 +2967,7 @@ ia64_estimate_size_before_relax (fragS *frag,
 }
 
 /* This function converts a rs_machine_dependent variant frag into a
-  normal fill frag with the unwind image from the the record list.  */
+  normal fill frag with the unwind image from the record list.  */
 void
 ia64_convert_frag (fragS *frag)
 {
@@ -3013,12 +3157,11 @@ dot_radix (int dummy ATTRIBUTE_UNUSED)
 
   if (is_it_end_of_statement ())
     return;
-  radix = input_line_pointer;
-  ch = get_symbol_end ();
+  ch = get_symbol_name (&radix);
   ia64_canonicalize_symbol_name (radix);
   if (strcasecmp (radix, "C"))
     as_bad (_("Radix `%s' unsupported or invalid"), radix);
-  *input_line_pointer = ch;
+  (void) restore_line_pointer (ch);
   demand_empty_rest_of_line ();
 }
 
@@ -3125,11 +3268,12 @@ add_unwind_entry (unw_rec_list *ptr, int sep)
 
   if (sep == ',')
     {
+      char *name;
       /* Parse a tag permitted for the current directive.  */
       int ch;
 
       SKIP_WHITESPACE ();
-      ch = get_symbol_end ();
+      ch = get_symbol_name (&name);
       /* FIXME: For now, just issue a warning that this isn't implemented.  */
       {
        static int warned;
@@ -3140,7 +3284,7 @@ add_unwind_entry (unw_rec_list *ptr, int sep)
            as_warn (_("Tags on unwind pseudo-ops aren't supported, yet"));
          }
       }
-      *input_line_pointer = ch;
+      (void) restore_line_pointer (ch);
     }
   if (sep != NOT_A_CHAR)
     demand_empty_rest_of_line ();
@@ -3186,7 +3330,7 @@ dot_vframe (int dummy ATTRIBUTE_UNUSED)
   if (! (unwind.prologue_mask & 2))
     add_unwind_entry (output_psp_gr (reg), NOT_A_CHAR);
   else if (reg != unwind.prologue_gr
-                 + (unsigned) popcount (unwind.prologue_mask & (-2 << 1)))
+                 + (unsigned) popcount (unwind.prologue_mask & -(2 << 1)))
     as_warn (_("Operand of .vframe contradicts .prologue"));
 }
 
@@ -3229,7 +3373,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED)
     e2.X_op = O_absent;
 
   reg1 = e1.X_add_number;
-  /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'.  */
+  /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'.  */
   if (e1.X_op != O_register)
     {
       as_bad (_("First operand to .save not a register"));
@@ -3268,7 +3412,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED)
       if (! (unwind.prologue_mask & 4))
        add_unwind_entry (output_pfs_gr (reg2), NOT_A_CHAR);
       else if (reg2 != unwind.prologue_gr
-                      + (unsigned) popcount (unwind.prologue_mask & (-4 << 1)))
+                      + (unsigned) popcount (unwind.prologue_mask & -(4 << 1)))
        as_warn (_("Second operand of .save contradicts .prologue"));
       break;
     case REG_AR + AR_LC:
@@ -3287,7 +3431,7 @@ dot_save (int dummy ATTRIBUTE_UNUSED)
       if (! (unwind.prologue_mask & 1))
        add_unwind_entry (output_preds_gr (reg2), NOT_A_CHAR);
       else if (reg2 != unwind.prologue_gr
-                      + (unsigned) popcount (unwind.prologue_mask & (-1 << 1)))
+                      + (unsigned) popcount (unwind.prologue_mask & -(1 << 1)))
        as_warn (_("Second operand of .save contradicts .prologue"));
       break;
     case REG_PRIUNAT:
@@ -3368,7 +3512,7 @@ dot_restorereg (int pred)
   add_unwind_entry (output_spill_reg (ab, reg, 0, 0, qp), sep);
 }
 
-static char *special_linkonce_name[] =
+static const char *special_linkonce_name[] =
   {
     ".gnu.linkonce.ia64unw.", ".gnu.linkonce.ia64unwi."
   };
@@ -3413,7 +3557,6 @@ start_unwind_section (const segT text_seg, int sec_index)
   char *sec_name;
   const char *prefix = special_section_name [sec_index];
   const char *suffix;
-  size_t prefix_len, suffix_len, sec_name_len;
 
   sec_text_name = segment_name (text_seg);
   text_name = sec_text_name;
@@ -3437,20 +3580,13 @@ start_unwind_section (const segT text_seg, int sec_index)
       suffix += sizeof (".gnu.linkonce.t.") - 1;
     }
 
-  prefix_len = strlen (prefix);
-  suffix_len = strlen (suffix);
-  sec_name_len = prefix_len + suffix_len;
-  sec_name = alloca (sec_name_len + 1);
-  memcpy (sec_name, prefix, prefix_len);
-  memcpy (sec_name + prefix_len, suffix, suffix_len);
-  sec_name [sec_name_len] = '\0';
+  sec_name = concat (prefix, suffix, NULL);
 
   /* Handle COMDAT group.  */
   if ((text_seg->flags & SEC_LINK_ONCE) != 0
       && (elf_section_flags (text_seg) & SHF_GROUP) != 0)
     {
       char *section;
-      size_t len, group_name_len;
       const char *group_name = elf_group_name (text_seg);
 
       if (group_name == NULL)
@@ -3458,31 +3594,23 @@ start_unwind_section (const segT text_seg, int sec_index)
          as_bad (_("Group section `%s' has no group signature"),
                  sec_text_name);
          ignore_rest_of_line ();
+         free (sec_name);
          return;
        }
-      /* We have to construct a fake section directive. */
-      group_name_len = strlen (group_name);
-      len = (sec_name_len
-            + 16                       /* ,"aG",@progbits,  */
-            + group_name_len           /* ,group_name  */
-            + 7);                      /* ,comdat  */
-
-      section = alloca (len + 1);
-      memcpy (section, sec_name, sec_name_len);
-      memcpy (section + sec_name_len, ",\"aG\",@progbits,", 16);
-      memcpy (section + sec_name_len + 16, group_name, group_name_len);
-      memcpy (section + len - 7, ",comdat", 7);
-      section [len] = '\0';
+
+      /* We have to construct a fake section directive.  */
+      section = concat (sec_name, ",\"aG\",@progbits,", group_name, ",comdat", NULL);
       set_section (section);
+      free (section);
     }
   else
     {
       set_section (sec_name);
-      bfd_set_section_flags (stdoutput, now_seg,
-                            SEC_LOAD | SEC_ALLOC | SEC_READONLY);
+      bfd_set_section_flags (now_seg, SEC_LOAD | SEC_ALLOC | SEC_READONLY);
     }
 
   elf_linked_to_section (now_seg) = text_seg;
+  free (sec_name);
 }
 
 static void
@@ -3533,7 +3661,7 @@ generate_unwind_image (const segT text_seg)
 
       /* Set expression which points to start of unwind descriptor area.  */
       unwind.info = expr_build_dot ();
-      
+
       frag_var (rs_machine_dependent, size, size, 0, 0,
                (offsetT) (long) unwind.personality_routine,
                (char *) list);
@@ -3636,7 +3764,7 @@ dot_savemem (int psprel)
   reg1 = e1.X_add_number;
   val = e2.X_add_number;
 
-  /* Make sure its a valid ar.xxx reg, OR its br0, aka 'rp'.  */
+  /* Make sure it's a valid ar.xxx reg, OR its br0, aka 'rp'.  */
   if (e1.X_op != O_register)
     {
       as_bad (_("First operand to .%s not a register"), po);
@@ -3981,7 +4109,7 @@ save_prologue_count (unsigned long lbl, unsigned int count)
     lpc->prologue_count = count;
   else
     {
-      label_prologue_count *new_lpc = xmalloc (sizeof (* new_lpc));
+      label_prologue_count *new_lpc = XNEW (label_prologue_count);
 
       new_lpc->next = unwind.saved_prologue_counts;
       new_lpc->label_number = lbl;
@@ -3991,7 +4119,7 @@ save_prologue_count (unsigned long lbl, unsigned int count)
 }
 
 static void
-free_saved_prologue_counts ()
+free_saved_prologue_counts (void)
 {
   label_prologue_count *lpc = unwind.saved_prologue_counts;
   label_prologue_count *next;
@@ -4078,16 +4206,16 @@ static void
 dot_personality (int dummy ATTRIBUTE_UNUSED)
 {
   char *name, *p, c;
+
   if (!in_procedure ("personality"))
     return;
   SKIP_WHITESPACE ();
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   p = input_line_pointer;
   unwind.personality_routine = symbol_find_or_make (name);
   unwind.force_unwind_entry = 1;
   *p = c;
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
   demand_empty_rest_of_line ();
 }
 
@@ -4117,8 +4245,7 @@ dot_proc (int dummy ATTRIBUTE_UNUSED)
   while (1)
     {
       SKIP_WHITESPACE ();
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       p = input_line_pointer;
       if (!*name)
        as_bad (_("Empty argument of .proc"));
@@ -4134,14 +4261,14 @@ dot_proc (int dummy ATTRIBUTE_UNUSED)
            }
          else
            {
-             pending = xmalloc (sizeof (*pending));
+             pending = XNEW (proc_pending);
              pending->sym = sym;
              last_pending = last_pending->next = pending;
            }
          symbol_get_bfdsym (sym)->flags |= BSF_FUNCTION;
        }
       *p = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       if (*input_line_pointer != ',')
        break;
       ++input_line_pointer;
@@ -4153,7 +4280,7 @@ dot_proc (int dummy ATTRIBUTE_UNUSED)
     }
   last_pending->next = NULL;
   demand_empty_rest_of_line ();
-  ia64_do_align (16);
+  do_align (4, NULL, 0, 0);
 
   unwind.prologue = 0;
   unwind.prologue_count = 0;
@@ -4208,12 +4335,14 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED)
        as_warn (_("Pointless use of zero first operand to .prologue"));
       else
        mask = e.X_add_number;
-       n = popcount (mask);
+
+      n = popcount (mask);
 
       if (sep == ',')
        parse_operand_and_eval (&e, 0);
       else
        e.X_op = O_absent;
+
       if (e.X_op == O_constant
          && e.X_add_number >= 0
          && e.X_add_number < 128)
@@ -4233,7 +4362,6 @@ dot_prologue (int dummy ATTRIBUTE_UNUSED)
          as_bad (_("Second operand to .prologue must be the first of %d general registers"), n);
          grsave = 0;
        }
-
     }
 
   if (mask)
@@ -4307,19 +4435,21 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
       e.X_add_number = 0;
       if (!S_IS_LOCAL (unwind.proc_pending.sym)
          && S_IS_DEFINED (unwind.proc_pending.sym))
-       e.X_add_symbol = symbol_temp_new (S_GET_SEGMENT (unwind.proc_pending.sym),
-                                         S_GET_VALUE (unwind.proc_pending.sym),
-                                         symbol_get_frag (unwind.proc_pending.sym));
+       e.X_add_symbol
+         = symbol_temp_new (S_GET_SEGMENT (unwind.proc_pending.sym),
+                            symbol_get_frag (unwind.proc_pending.sym),
+                            S_GET_VALUE (unwind.proc_pending.sym));
       else
        e.X_add_symbol = unwind.proc_pending.sym;
-      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e);
+      ia64_cons_fix_new (frag_now, where, bytes_per_address, &e,
+                        BFD_RELOC_NONE);
 
       e.X_op = O_pseudo_fixup;
       e.X_op_symbol = pseudo_func[FUNC_SEG_RELATIVE].u.sym;
       e.X_add_number = 0;
       e.X_add_symbol = proc_end;
       ia64_cons_fix_new (frag_now, where + bytes_per_address,
-                        bytes_per_address, &e);
+                        bytes_per_address, &e, BFD_RELOC_NONE);
 
       if (unwind.info)
        {
@@ -4328,7 +4458,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
          e.X_add_number = 0;
          e.X_add_symbol = unwind.info;
          ia64_cons_fix_new (frag_now, where + (bytes_per_address * 2),
-                            bytes_per_address, &e);
+                            bytes_per_address, &e, BFD_RELOC_NONE);
        }
     }
   subseg_set (saved_seg, saved_subseg);
@@ -4354,12 +4484,11 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
                    S_SET_SIZE (sym, frag_now_fix () - S_GET_VALUE (sym));
                  else
                    {
-                     symbol_get_obj (sym)->size =
-                       (expressionS *) xmalloc (sizeof (expressionS));
+                     symbol_get_obj (sym)->size = XNEW (expressionS);
                      symbol_get_obj (sym)->size->X_op = O_subtract;
                      symbol_get_obj (sym)->size->X_add_symbol
                        = symbol_new (FAKE_LABEL_NAME, now_seg,
-                                     frag_now_fix (), frag_now);
+                                     frag_now, frag_now_fix ());
                      symbol_get_obj (sym)->size->X_op_symbol = sym;
                      symbol_get_obj (sym)->size->X_add_number = 0;
                    }
@@ -4374,8 +4503,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
       char *name, *p, c;
 
       SKIP_WHITESPACE ();
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       p = input_line_pointer;
       if (!*name)
        (md.unwind_check == unwind_check_warning
@@ -4397,7 +4525,7 @@ dot_endp (int dummy ATTRIBUTE_UNUSED)
            as_warn (_("`%s' was not specified with previous .proc"), name);
        }
       *p = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       if (*input_line_pointer != ',')
        break;
       ++input_line_pointer;
@@ -4475,7 +4603,7 @@ dot_rot (int type)
   /* First, remove existing names from hash table.  */
   for (dr = md.dynreg[type]; dr && dr->num_regs; dr = dr->next)
     {
-      hash_delete (md.dynreg_hash, dr->name, FALSE);
+      str_hash_delete (md.dynreg_hash, dr->name);
       /* FIXME: Free dr->name.  */
       dr->num_regs = 0;
     }
@@ -4483,12 +4611,11 @@ dot_rot (int type)
   drpp = &md.dynreg[type];
   while (1)
     {
-      start = input_line_pointer;
-      ch = get_symbol_end ();
+      ch = get_symbol_name (&start);
       len = strlen (ia64_canonicalize_symbol_name (start));
       *input_line_pointer = ch;
 
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       if (*input_line_pointer != '[')
        {
          as_bad (_("Expected '['"));
@@ -4542,11 +4669,11 @@ dot_rot (int type)
 
       if (!*drpp)
        {
-         *drpp = obstack_alloc (&notes, sizeof (*dr));
+         *drpp = XOBNEW (&notes, struct dynreg);
          memset (*drpp, 0, sizeof (*dr));
        }
 
-      name = obstack_alloc (&notes, len + 1);
+      name = XOBNEWVEC (&notes, char, len + 1);
       memcpy (name, start, len);
       name[len] = '\0';
 
@@ -4557,7 +4684,7 @@ dot_rot (int type)
       drpp = &dr->next;
       base_reg += num_regs;
 
-      if (hash_insert (md.dynreg_hash, name, dr))
+      if (str_hash_insert (md.dynreg_hash, name, dr, 0) != NULL)
        {
          as_bad (_("Attempt to redefine register set `%s'"), name);
          obstack_free (&notes, name);
@@ -4614,8 +4741,7 @@ dot_psr (int dummy ATTRIBUTE_UNUSED)
 
   while (1)
     {
-      option = input_line_pointer;
-      ch = get_symbol_end ();
+      ch = get_symbol_name (&option);
       if (strcmp (option, "lsb") == 0)
        md.flags &= ~EF_IA_64_BE;
       else if (strcmp (option, "msb") == 0)
@@ -4628,7 +4754,7 @@ dot_psr (int dummy ATTRIBUTE_UNUSED)
        as_bad (_("Unknown psr option `%s'"), option);
       *input_line_pointer = ch;
 
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       if (*input_line_pointer != ',')
        break;
 
@@ -4651,36 +4777,21 @@ cross_section (int ref, void (*builder) (int), int ua)
   char *start, *end;
   int saved_auto_align;
   unsigned int section_count;
+  char *name;
+  char c;
 
   SKIP_WHITESPACE ();
   start = input_line_pointer;
-  if (*start == '"')
-    {
-      int len;
-      char *name;
-
-      name = demand_copy_C_string (&len);
-      obstack_free(&notes, name);
-      if (!name)
-       {
-         ignore_rest_of_line ();
-         return;
-       }
-    }
-  else
+  c = get_symbol_name (&name);
+  if (input_line_pointer == start)
     {
-      char c = get_symbol_end ();
-
-      if (input_line_pointer == start)
-       {
-         as_bad (_("Missing section name"));
-         ignore_rest_of_line ();
-         return;
-       }
-      *input_line_pointer = c;
+      as_bad (_("Missing section name"));
+      ignore_rest_of_line ();
+      return;
     }
+  * input_line_pointer = c;
+  SKIP_WHITESPACE_AFTER_NAME ();
   end = input_line_pointer;
-  SKIP_WHITESPACE ();
   if (*input_line_pointer != ',')
     {
       as_bad (_("Comma expected after section name"));
@@ -4722,20 +4833,20 @@ stmt_float_cons (int kind)
   switch (kind)
     {
     case 'd':
-      alignment = 8;
+      alignment = 3;
       break;
 
     case 'x':
     case 'X':
-      alignment = 16;
+      alignment = 4;
       break;
 
     case 'f':
     default:
-      alignment = 4;
+      alignment = 2;
       break;
     }
-  ia64_do_align (alignment);
+  do_align (alignment, NULL, 0, 0);
   float_cons (kind);
 }
 
@@ -4871,7 +4982,7 @@ static void
 print_prmask (valueT mask)
 {
   int regno;
-  char *comma = "";
+  const char *comma = "";
   for (regno = 0; regno < 64; regno++)
     {
       if (mask & ((valueT) 1 << regno))
@@ -4913,8 +5024,11 @@ dot_pred_rel (int type)
        }
       else if (*input_line_pointer == '@')
        {
-         char *form = ++input_line_pointer;
-         char c = get_symbol_end();
+         char *form;
+         char c;
+
+         ++input_line_pointer;
+         c = get_symbol_name (&form);
 
          if (strcmp (form, "mutex") == 0)
            type = 'm';
@@ -4922,7 +5036,7 @@ dot_pred_rel (int type)
            type = 'c';
          else if (strcmp (form, "imply") == 0)
            type = 'i';
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
       else
        {
@@ -5053,24 +5167,20 @@ dot_pred_rel (int type)
 static void
 dot_entry (int dummy ATTRIBUTE_UNUSED)
 {
-  const char *err;
   char *name;
   int c;
   symbolS *symbolP;
 
   do
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       symbolP = symbol_find_or_make (name);
 
-      err = hash_insert (md.entry_hash, S_GET_NAME (symbolP), (void *) symbolP);
-      if (err)
-       as_fatal (_("Inserting \"%s\" into entry hint table failed: %s"),
-                 name, err);
+      if (str_hash_insert (md.entry_hash, S_GET_NAME (symbolP), symbolP, 0))
+       as_bad (_("duplicate entry hint %s"), name);
 
       *input_line_pointer = c;
-      SKIP_WHITESPACE ();
+      SKIP_WHITESPACE_AFTER_NAME ();
       c = *input_line_pointer;
       if (c == ',')
        {
@@ -5221,6 +5331,10 @@ const pseudo_typeS md_pseudo_table[] =
     {"4byte", stmt_cons_ua, 4},
     {"8byte", stmt_cons_ua, 8},
 
+#ifdef TE_VMS
+    {"vms_common", obj_elf_vms_common, 0},
+#endif
+
     { NULL, 0, 0 }
   };
 
@@ -5262,15 +5376,12 @@ pseudo_opcode[] =
 static symbolS *
 declare_register (const char *name, unsigned int regnum)
 {
-  const char *err;
   symbolS *sym;
 
-  sym = symbol_create (name, reg_section, regnum, &zero_address_frag);
+  sym = symbol_create (name, reg_section, &zero_address_frag, regnum);
 
-  err = hash_insert (md.reg_hash, S_GET_NAME (sym), (void *) sym);
-  if (err)
-    as_fatal ("Inserting \"%s\" into register table failed: %s",
-             name, err);
+  if (str_hash_insert (md.reg_hash, S_GET_NAME (sym), sym, 0) != NULL)
+    as_fatal (_("duplicate %s"), name);
 
   return sym;
 }
@@ -5417,6 +5528,12 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
        return OPERAND_MATCH;
       break;
 
+    case IA64_OPND_DAHR3:
+      if (e->X_op == O_register && e->X_add_number >= REG_DAHR
+         && e->X_add_number < REG_DAHR + 8)
+       return OPERAND_MATCH;
+      break;
+
     case IA64_OPND_F1:
     case IA64_OPND_F2:
     case IA64_OPND_F3:
@@ -5461,6 +5578,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
     case IA64_OPND_PKR_R3:
     case IA64_OPND_PMC_R3:
     case IA64_OPND_PMD_R3:
+    case IA64_OPND_DAHR_R3:
     case IA64_OPND_RR_R3:
       if (e->X_op == O_index && e->X_op_symbol
          && (S_GET_VALUE (e->X_op_symbol) - IND_CPUID
@@ -5512,6 +5630,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
       /* SOR must be an integer multiple of 8 */
       if (e->X_op == O_constant && e->X_add_number & 0x7)
        return OPERAND_OUT_OF_RANGE;
+      /* Fall through.  */
     case IA64_OPND_SOF:
     case IA64_OPND_SOL:
       if (e->X_op == O_constant)
@@ -5581,6 +5700,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
     case IA64_OPND_IMMU2:
     case IA64_OPND_IMMU7a:
     case IA64_OPND_IMMU7b:
+    case IA64_OPND_IMMU16:
+    case IA64_OPND_IMMU19:
     case IA64_OPND_IMMU21:
     case IA64_OPND_IMMU24:
     case IA64_OPND_MBTYPE4:
@@ -5665,6 +5786,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
     case IA64_OPND_IMM14:
     case IA64_OPND_IMM22:
       relocatable = 1;
+      /* Fall through.  */
     case IA64_OPND_IMM1:
     case IA64_OPND_IMM8:
     case IA64_OPND_IMM8U4:
@@ -5712,9 +5834,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
          /* Sign-extend 32-bit unsigned numbers, so that the following range
             checks will work.  */
          val = e->X_add_number;
-         if (((val & (~(bfd_vma) 0 << 32)) == 0)
-             && ((val & ((bfd_vma) 1 << 31)) != 0))
-           val = ((val << 32) >> 32);
+         if ((val & (~(bfd_vma) 0 << 32)) == 0)
+           val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
 
          /* Check for 0x100000000.  This is valid because
             0x100000000-1 is the same as ((uint32_t) -1).  */
@@ -5752,9 +5873,8 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
          /* Sign-extend 32-bit unsigned numbers, so that the following range
             checks will work.  */
          val = e->X_add_number;
-         if (((val & (~(bfd_vma) 0 << 32)) == 0)
-             && ((val & ((bfd_vma) 1 << 31)) != 0))
-           val = ((val << 32) >> 32);
+         if ((val & (~(bfd_vma) 0 << 32)) == 0)
+           val = (val ^ ((bfd_vma) 1 << 31)) - ((bfd_vma) 1 << 31);
        }
       else
        val = e->X_add_number;
@@ -5804,6 +5924,7 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
          ++CURR_SLOT.num_fixups;
          return OPERAND_MATCH;
        }
+      /* Fall through.  */
     case IA64_OPND_TAG13:
     case IA64_OPND_TAG13b:
       switch (e->X_op)
@@ -5837,6 +5958,39 @@ operand_match (const struct ia64_opcode *idesc, int res_index, expressionS *e)
       ++CURR_SLOT.num_fixups;
       return OPERAND_MATCH;
 
+    case IA64_OPND_STRD5b:
+      if (e->X_op == O_constant)
+       {
+         /* 5-bit signed scaled by 64 */
+         if ((e->X_add_number <=       ( 0xf  << 6 ))
+              && (e->X_add_number >=  -( 0x10 << 6 )))
+           {
+
+             /* Must be a multiple of 64 */
+             if ((e->X_add_number & 0x3f) != 0)
+               as_warn (_("stride must be a multiple of 64; lower 6 bits ignored"));
+
+             e->X_add_number &= ~ 0x3f;
+             return OPERAND_MATCH;
+           }
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
+      break;
+    case IA64_OPND_CNT6a:
+      if (e->X_op == O_constant)
+       {
+         /* 6-bit unsigned biased by 1 -- count 0 is meaningless */
+         if ((e->X_add_number     <=   64)
+              && (e->X_add_number > 0) )
+           {
+             return OPERAND_MATCH;
+           }
+         else
+           return OPERAND_OUT_OF_RANGE;
+       }
+      break;
+
     default:
       break;
     }
@@ -5942,10 +6096,12 @@ parse_operands (struct ia64_opcode *idesc)
 
   for (; ; ++i)
     {
-      if (i < NELEMS (CURR_SLOT.opnd)) 
+      if (i < NELEMS (CURR_SLOT.opnd))
        {
-         sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=',
-                                         idesc->operands[i]);
+         enum ia64_opnd op = IA64_OPND_NIL;
+         if (i < NELEMS (idesc->operands))
+           op = idesc->operands[i];
+         sep = parse_operand_maybe_eval (CURR_SLOT.opnd + i, '=', op);
          if (CURR_SLOT.opnd[i].X_op == O_absent)
            break;
        }
@@ -6287,6 +6443,10 @@ build_insn (struct slot *slot, bfd_vma *insnp)
          val -= REG_CR;
          break;
 
+       case IA64_OPND_DAHR3:
+         val -= REG_DAHR;
+         break;
+
        case IA64_OPND_F1:
        case IA64_OPND_F2:
        case IA64_OPND_F3:
@@ -6313,6 +6473,7 @@ build_insn (struct slot *slot, bfd_vma *insnp)
        case IA64_OPND_PKR_R3:
        case IA64_OPND_PMC_R3:
        case IA64_OPND_PMD_R3:
+       case IA64_OPND_DAHR_R3:
        case IA64_OPND_RR_R3:
          val -= REG_GR;
          break;
@@ -6728,15 +6889,6 @@ emit_one_bundle (void)
          md.slot[curr].unwind_record = NULL;
        }
 
-      if (required_unit == IA64_UNIT_L)
-       {
-         know (i == 1);
-         /* skip one slot for long/X-unit instructions */
-         ++i;
-       }
-      --md.num_slots_in_use;
-      last_slot = i;
-
       for (j = 0; j < md.slot[curr].num_fixups; ++j)
        {
          ifix = md.slot[curr].fixup + j;
@@ -6749,6 +6901,17 @@ emit_one_bundle (void)
 
       end_of_insn_group = md.slot[curr].end_of_insn_group;
 
+      /* This adjustment to "i" must occur after the fix, otherwise the fix
+        is assigned to the wrong slot, and the VMS linker complains.  */
+      if (required_unit == IA64_UNIT_L)
+       {
+         know (i == 1);
+         /* skip one slot for long/X-unit instructions */
+         ++i;
+       }
+      --md.num_slots_in_use;
+      last_slot = i;
+
       /* clear slot:  */
       ia64_free_opcode (md.slot[curr].idesc);
       memset (md.slot + curr, 0, sizeof (md.slot[curr]));
@@ -6803,7 +6966,7 @@ emit_one_bundle (void)
        as_bad_where (md.slot[curr].src_file, md.slot[curr].src_line,
                      _("Missing '}' at end of file"));
     }
-       
+
   know (md.num_slots_in_use < NUM_SLOTS);
 
   t0 = end_of_insn_group | (template_val << 1) | (insn[0] << 5) | (insn[1] << 46);
@@ -6814,7 +6977,7 @@ emit_one_bundle (void)
 }
 
 int
-md_parse_option (int c, char *arg)
+md_parse_option (int c, const char *arg)
 {
 
   switch (c)
@@ -6990,7 +7153,9 @@ IA-64 options:\n\
                          unwind directive check (default -munwind-check=warning)\n\
   -mhint.b=[ok|warning|error]\n\
                          hint.b check (default -mhint.b=error)\n\
-  -x | -xexplicit        turn on dependency violation checking\n\
+  -x | -xexplicit        turn on dependency violation checking\n"), stream);
+  /* Note for translators: "automagically" can be translated as "automatically" here.  */
+  fputs (_("\
   -xauto                 automagically remove dependency violations (default)\n\
   -xnone                 turn off dependency violation checking\n\
   -xdebug                debug dependency violation checker\n\
@@ -7073,90 +7238,94 @@ void
 md_begin (void)
 {
   int i, j, k, t, goodness, best, ok;
-  const char *err;
-  char name[8];
 
   md.auto_align = 1;
   md.explicit_mode = md.default_explicit_mode;
 
-  bfd_set_section_alignment (stdoutput, text_section, 4);
+  bfd_set_section_alignment (text_section, 4);
 
   /* Make sure function pointers get initialized.  */
   target_big_endian = -1;
   dot_byteorder (default_big_endian);
 
-  alias_hash = hash_new ();
-  alias_name_hash = hash_new ();
-  secalias_hash = hash_new ();
-  secalias_name_hash = hash_new ();
+  alias_hash = str_htab_create ();
+  alias_name_hash = str_htab_create ();
+  secalias_hash = str_htab_create ();
+  secalias_name_hash = str_htab_create ();
 
   pseudo_func[FUNC_DTP_MODULE].u.sym =
-    symbol_new (".<dtpmod>", undefined_section, FUNC_DTP_MODULE,
-               &zero_address_frag);
+    symbol_new (".<dtpmod>", undefined_section,
+               &zero_address_frag, FUNC_DTP_MODULE);
 
   pseudo_func[FUNC_DTP_RELATIVE].u.sym =
-    symbol_new (".<dtprel>", undefined_section, FUNC_DTP_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<dtprel>", undefined_section,
+               &zero_address_frag, FUNC_DTP_RELATIVE);
 
   pseudo_func[FUNC_FPTR_RELATIVE].u.sym =
-    symbol_new (".<fptr>", undefined_section, FUNC_FPTR_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<fptr>", undefined_section,
+               &zero_address_frag, FUNC_FPTR_RELATIVE);
 
   pseudo_func[FUNC_GP_RELATIVE].u.sym =
-    symbol_new (".<gprel>", undefined_section, FUNC_GP_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<gprel>", undefined_section,
+               &zero_address_frag, FUNC_GP_RELATIVE);
 
   pseudo_func[FUNC_LT_RELATIVE].u.sym =
-    symbol_new (".<ltoff>", undefined_section, FUNC_LT_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<ltoff>", undefined_section,
+               &zero_address_frag, FUNC_LT_RELATIVE);
 
   pseudo_func[FUNC_LT_RELATIVE_X].u.sym =
-    symbol_new (".<ltoffx>", undefined_section, FUNC_LT_RELATIVE_X,
-               &zero_address_frag);
+    symbol_new (".<ltoffx>", undefined_section,
+               &zero_address_frag, FUNC_LT_RELATIVE_X);
 
   pseudo_func[FUNC_PC_RELATIVE].u.sym =
-    symbol_new (".<pcrel>", undefined_section, FUNC_PC_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<pcrel>", undefined_section,
+               &zero_address_frag, FUNC_PC_RELATIVE);
 
   pseudo_func[FUNC_PLT_RELATIVE].u.sym =
-    symbol_new (".<pltoff>", undefined_section, FUNC_PLT_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<pltoff>", undefined_section,
+               &zero_address_frag, FUNC_PLT_RELATIVE);
 
   pseudo_func[FUNC_SEC_RELATIVE].u.sym =
-    symbol_new (".<secrel>", undefined_section, FUNC_SEC_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<secrel>", undefined_section,
+               &zero_address_frag, FUNC_SEC_RELATIVE);
 
   pseudo_func[FUNC_SEG_RELATIVE].u.sym =
-    symbol_new (".<segrel>", undefined_section, FUNC_SEG_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<segrel>", undefined_section,
+               &zero_address_frag, FUNC_SEG_RELATIVE);
 
   pseudo_func[FUNC_TP_RELATIVE].u.sym =
-    symbol_new (".<tprel>", undefined_section, FUNC_TP_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<tprel>", undefined_section,
+               &zero_address_frag, FUNC_TP_RELATIVE);
 
   pseudo_func[FUNC_LTV_RELATIVE].u.sym =
-    symbol_new (".<ltv>", undefined_section, FUNC_LTV_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<ltv>", undefined_section,
+               &zero_address_frag, FUNC_LTV_RELATIVE);
 
   pseudo_func[FUNC_LT_FPTR_RELATIVE].u.sym =
-    symbol_new (".<ltoff.fptr>", undefined_section, FUNC_LT_FPTR_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<ltoff.fptr>", undefined_section,
+               &zero_address_frag, FUNC_LT_FPTR_RELATIVE);
 
   pseudo_func[FUNC_LT_DTP_MODULE].u.sym =
-    symbol_new (".<ltoff.dtpmod>", undefined_section, FUNC_LT_DTP_MODULE,
-               &zero_address_frag);
+    symbol_new (".<ltoff.dtpmod>", undefined_section,
+               &zero_address_frag, FUNC_LT_DTP_MODULE);
 
   pseudo_func[FUNC_LT_DTP_RELATIVE].u.sym =
-    symbol_new (".<ltoff.dptrel>", undefined_section, FUNC_LT_DTP_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<ltoff.dptrel>", undefined_section,
+               &zero_address_frag, FUNC_LT_DTP_RELATIVE);
 
   pseudo_func[FUNC_LT_TP_RELATIVE].u.sym =
-    symbol_new (".<ltoff.tprel>", undefined_section, FUNC_LT_TP_RELATIVE,
-               &zero_address_frag);
+    symbol_new (".<ltoff.tprel>", undefined_section,
+               &zero_address_frag, FUNC_LT_TP_RELATIVE);
 
   pseudo_func[FUNC_IPLT_RELOC].u.sym =
-    symbol_new (".<iplt>", undefined_section, FUNC_IPLT_RELOC,
-               &zero_address_frag);
+    symbol_new (".<iplt>", undefined_section,
+               &zero_address_frag, FUNC_IPLT_RELOC);
+
+#ifdef TE_VMS
+  pseudo_func[FUNC_SLOTCOUNT_RELOC].u.sym =
+    symbol_new (".<slotcount>", undefined_section,
+               &zero_address_frag, FUNC_SLOTCOUNT_RELOC);
+#endif
 
  if (md.tune != itanium1)
    {
@@ -7231,20 +7400,16 @@ md_begin (void)
   for (i = 0; i < NUM_SLOTS; ++i)
     md.slot[i].user_template = -1;
 
-  md.pseudo_hash = hash_new ();
+  md.pseudo_hash = str_htab_create ();
   for (i = 0; i < NELEMS (pseudo_opcode); ++i)
-    {
-      err = hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
-                        (void *) (pseudo_opcode + i));
-      if (err)
-       as_fatal (_("ia64.md_begin: can't hash `%s': %s"),
-                 pseudo_opcode[i].name, err);
-    }
+    if (str_hash_insert (md.pseudo_hash, pseudo_opcode[i].name,
+                        pseudo_opcode + i, 0) != NULL)
+      as_fatal (_("duplicate %s"), pseudo_opcode[i].name);
 
-  md.reg_hash = hash_new ();
-  md.dynreg_hash = hash_new ();
-  md.const_hash = hash_new ();
-  md.entry_hash = hash_new ();
+  md.reg_hash = str_htab_create ();
+  md.dynreg_hash = str_htab_create ();
+  md.const_hash = str_htab_create ();
+  md.entry_hash = str_htab_create ();
 
   /* general registers:  */
   declare_register_set ("r", 128, REG_GR);
@@ -7277,6 +7442,9 @@ md_begin (void)
   for (i = 0; i < NELEMS (cr); ++i)
     declare_register (cr[i].name, REG_CR + cr[i].regnum);
 
+  /* dahr registers:  */
+  declare_register_set ("dahr", 8, REG_DAHR);
+
   declare_register ("ip", REG_IP);
   declare_register ("cfm", REG_CFM);
   declare_register ("psr", REG_PSR);
@@ -7294,13 +7462,8 @@ md_begin (void)
   declare_register ("psp", REG_PSP);
 
   for (i = 0; i < NELEMS (const_bits); ++i)
-    {
-      err = hash_insert (md.const_hash, const_bits[i].name,
-                        (void *) (const_bits + i));
-      if (err)
-       as_fatal (_("Inserting \"%s\" into constant hash table failed: %s"),
-                 name, err);
-    }
+    if (str_hash_insert (md.const_hash, const_bits[i].name, const_bits + i, 0))
+      as_fatal (_("duplicate %s"), const_bits[i].name);
 
   /* Set the architecture and machine depending on defaults and command line
      options.  */
@@ -7529,8 +7692,7 @@ ia64_unrecognized_line (int ch)
           recognize labels.  */
        if (is_name_beginner (*input_line_pointer))
          {
-           s = input_line_pointer;
-           c = get_symbol_end ();
+           c = get_symbol_name (&s);
          }
        else if (LOCAL_LABELS_FB
                 && ISDIGIT (*input_line_pointer))
@@ -7590,7 +7752,7 @@ ia64_frob_label (struct symbol *sym)
      labels.  */
   if (defining_tag)
     {
-      fix = obstack_alloc (&notes, sizeof (*fix));
+      fix = XOBNEW (&notes, struct label_fix);
       fix->sym = sym;
       fix->next = CURR_SLOT.tag_fixups;
       fix->dw2_mark_labels = FALSE;
@@ -7599,10 +7761,10 @@ ia64_frob_label (struct symbol *sym)
       return;
     }
 
-  if (bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
+  if (bfd_section_flags (now_seg) & SEC_CODE)
     {
       md.last_text_seg = now_seg;
-      fix = obstack_alloc (&notes, sizeof (*fix));
+      fix = XOBNEW (&notes, struct label_fix);
       fix->sym = sym;
       fix->next = CURR_SLOT.label_fixups;
       fix->dw2_mark_labels = dwarf2_loc_mark_labels;
@@ -7612,9 +7774,8 @@ ia64_frob_label (struct symbol *sym)
       if (md.path == md.maxpaths)
        {
          md.maxpaths += 20;
-         md.entry_labels = (const char **)
-           xrealloc ((void *) md.entry_labels,
-                     md.maxpaths * sizeof (char *));
+         md.entry_labels = XRESIZEVEC (const char *, md.entry_labels,
+                                       md.maxpaths);
        }
       md.entry_labels[md.path++] = S_GET_NAME (sym);
     }
@@ -7627,9 +7788,9 @@ ia64_frob_label (struct symbol *sym)
 int
 ia64_frob_symbol (struct symbol *sym)
 {
-  if ((S_GET_SEGMENT (sym) == &bfd_und_section && ! symbol_used_p (sym) &&
+  if ((S_GET_SEGMENT (sym) == bfd_und_section_ptr && ! symbol_used_p (sym) &&
        ELF_ST_VISIBILITY (S_GET_OTHER (sym)) == STV_DEFAULT)
-      || (S_GET_SEGMENT (sym) == &bfd_abs_section
+      || (S_GET_SEGMENT (sym) == bfd_abs_section_ptr
          && ! S_IS_EXTERNAL (sym)))
     return 1;
   return 0;
@@ -7640,7 +7801,7 @@ void
 ia64_flush_pending_output (void)
 {
   if (!md.keep_pending_output
-      && bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE)
+      && bfd_section_flags (now_seg) & SEC_CODE)
     {
       /* ??? This causes many unnecessary stop bits to be emitted.
         Unfortunately, it isn't clear if it is safe to remove this.  */
@@ -7744,6 +7905,15 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP)
            }
          /* Skip ')'.  */
          ++input_line_pointer;
+#ifdef TE_VMS
+          if (idx == FUNC_SLOTCOUNT_RELOC)
+            {
+              /* @slotcount can accept any expression.  Canonicalize.  */
+              e->X_add_symbol = make_expr_symbol (e);
+              e->X_op = O_symbol;
+              e->X_add_number = 0;
+            }
+#endif
          if (e->X_op != O_symbol)
            {
              if (e->X_op != O_pseudo_fixup)
@@ -7796,7 +7966,7 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP)
     }
 
   /* first see if NAME is a known register name:  */
-  sym = hash_find (md.reg_hash, name);
+  sym = str_hash_find (md.reg_hash, name);
   if (sym)
     {
       e->X_op = O_register;
@@ -7804,7 +7974,7 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP)
       return 1;
     }
 
-  cdesc = hash_find (md.const_hash, name);
+  cdesc = str_hash_find (md.const_hash, name);
   if (cdesc)
     {
       e->X_op = O_constant;
@@ -7868,10 +8038,9 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP)
        }
     }
 
-  end = alloca (strlen (name) + 1);
-  strcpy (end, name);
+  end = xstrdup (name);
   name = ia64_canonicalize_symbol_name (end);
-  if ((dr = hash_find (md.dynreg_hash, name)))
+  if ((dr = str_hash_find (md.dynreg_hash, name)))
     {
       /* We've got ourselves the name of a rotating register set.
         Store the base register number in the low 16 bits of
@@ -7879,8 +8048,10 @@ ia64_parse_name (char *name, expressionS *e, char *nextcharP)
         bits.  */
       e->X_op = O_register;
       e->X_add_number = dr->base | (dr->num_regs << 16);
+      free (end);
       return 1;
     }
+  free (end);
   return 0;
 }
 
@@ -8521,6 +8692,22 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note)
        }
       break;
 
+    case IA64_RS_DAHR:
+      if (note == 0)
+       {
+         if (idesc->operands[!rsrc_write] == IA64_OPND_DAHR3)
+           {
+             specs[count] = tmpl;
+             specs[count++].index =
+               CURR_SLOT.opnd[!rsrc_write].X_add_number - REG_DAHR;
+           }
+       }
+      else
+       {
+         UNHANDLED;
+       }
+      break;
+
     case IA64_RS_FR:
     case IA64_RS_FRb:
       if (note != 1)
@@ -8595,6 +8782,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note)
                      || idesc->operands[i] == IA64_OPND_PKR_R3
                      || idesc->operands[i] == IA64_OPND_PMC_R3
                      || idesc->operands[i] == IA64_OPND_PMD_R3
+                     || idesc->operands[i] == IA64_OPND_DAHR_R3
                      || idesc->operands[i] == IA64_OPND_RR_R3
                      || ((i >= idesc->num_outputs)
                          && (idesc->operands[i] == IA64_OPND_R1
@@ -9080,6 +9268,7 @@ dep->name, idesc->name, (rsrc_write?"write":"read"), note)
                    {
                      specs[count++] = tmpl;
                    }
+                 /* Fall through.  */
                case AR_RSC:
                  if (!rsrc_write &&
                      (regno == AR_BSPSTORE
@@ -9408,7 +9597,7 @@ update_qp_mutex (valueT mask)
                  print_prmask (qp_mutexes[i].prmask);
                  fprintf (stderr, "\n");
                }
-             
+
              /* Deal with the old mutex with more than 3+ PRs only if
                 the new mutex on the same execution path with it.
 
@@ -9421,7 +9610,7 @@ update_qp_mutex (valueT mask)
                  if (add == 0
                      && (qp_mutexes[i].prmask & mask) == mask)
                    add = 1;
-                 
+
                  qp_mutexes[i].prmask &= ~mask;
                  if (qp_mutexes[i].prmask & (qp_mutexes[i].prmask - 1))
                    {
@@ -9431,7 +9620,7 @@ update_qp_mutex (valueT mask)
                      i++;
                    }
                }
-             
+
              if (keep == 0)
                /* Remove the mutex.  */
                qp_mutexes[i] = qp_mutexes[--qp_mutexeslen];
@@ -9528,9 +9717,7 @@ add_qp_imply (int p1, int p2)
   if (qp_implieslen == qp_impliestotlen)
     {
       qp_impliestotlen += 20;
-      qp_implies = (struct qp_imply *)
-       xrealloc ((void *) qp_implies,
-                 qp_impliestotlen * sizeof (struct qp_imply));
+      qp_implies = XRESIZEVEC (struct qp_imply, qp_implies, qp_impliestotlen);
     }
   if (md.debug_dv)
     fprintf (stderr, "  Registering PR%d implies PR%d\n", p1, p2);
@@ -9573,9 +9760,7 @@ add_qp_mutex (valueT mask)
   if (qp_mutexeslen == qp_mutexestotlen)
     {
       qp_mutexestotlen += 20;
-      qp_mutexes = (struct qpmutex *)
-       xrealloc ((void *) qp_mutexes,
-                 qp_mutexestotlen * sizeof (struct qpmutex));
+      qp_mutexes = XRESIZEVEC (struct qpmutex, qp_mutexes, qp_mutexestotlen);
     }
   if (md.debug_dv)
     {
@@ -9989,9 +10174,7 @@ mark_resource (struct ia64_opcode *idesc ATTRIBUTE_UNUSED,
   if (regdepslen == regdepstotlen)
     {
       regdepstotlen += 20;
-      regdeps = (struct rsrc *)
-       xrealloc ((void *) regdeps,
-                 regdepstotlen * sizeof (struct rsrc));
+      regdeps = XRESIZEVEC (struct rsrc, regdeps, regdepstotlen);
     }
 
   regdeps[regdepslen] = *spec;
@@ -10068,7 +10251,7 @@ remove_marked_resource (struct rsrc *rs)
     case IA64_DVS_SPECIFIC:
       if (md.debug_dv)
        fprintf (stderr, "Implementation-specific, assume worst case...\n");
-      /* ...fall through...  */
+      /* Fall through.  */
     case IA64_DVS_INSTR:
       if (md.debug_dv)
        fprintf (stderr, "Inserting instr serialization\n");
@@ -10463,7 +10646,8 @@ check_dv (struct ia64_opcode *idesc)
 void
 md_assemble (char *str)
 {
-  char *saved_input_line_pointer, *mnemonic;
+  char *saved_input_line_pointer, *temp;
+  const char *mnemonic;
   const struct pseudo_opcode *pdesc;
   struct ia64_opcode *idesc;
   unsigned char qp_regno;
@@ -10475,12 +10659,12 @@ md_assemble (char *str)
 
   /* extract the opcode (mnemonic):  */
 
-  mnemonic = input_line_pointer;
-  ch = get_symbol_end ();
-  pdesc = (struct pseudo_opcode *) hash_find (md.pseudo_hash, mnemonic);
+  ch = get_symbol_name (&temp);
+  mnemonic = temp;
+  pdesc = (struct pseudo_opcode *) str_hash_find (md.pseudo_hash, mnemonic);
   if (pdesc)
     {
-      *input_line_pointer = ch;
+      (void) restore_line_pointer (ch);
       (*pdesc->handler) (pdesc->arg);
       goto done;
     }
@@ -10488,7 +10672,7 @@ md_assemble (char *str)
   /* Find the instruction descriptor matching the arguments.  */
 
   idesc = ia64_find_opcode (mnemonic);
-  *input_line_pointer = ch;
+  (void) restore_line_pointer (ch);
   if (!idesc)
     {
       as_bad (_("Unknown opcode `%s'"), mnemonic);
@@ -10552,7 +10736,7 @@ md_assemble (char *str)
     {
       enum ia64_opnd opnd1, opnd2;
       int rop;
-      
+
       opnd1 = idesc->operands[0];
       opnd2 = idesc->operands[1];
       if (opnd1 == IA64_OPND_AR3)
@@ -10630,7 +10814,7 @@ md_assemble (char *str)
   /* Build the instruction.  */
   CURR_SLOT.qp_regno = qp_regno;
   CURR_SLOT.idesc = idesc;
-  as_where (&CURR_SLOT.src_file, &CURR_SLOT.src_line);
+  CURR_SLOT.src_file = as_where (&CURR_SLOT.src_line);
   dwarf2_where (&CURR_SLOT.debug_line);
   dwarf2_consume_line_info ();
 
@@ -10788,7 +10972,7 @@ ia64_pcrel_from_section (fixS *fix, segT sec)
 {
   unsigned long off = fix->fx_frag->fr_address + fix->fx_where;
 
-  if (bfd_get_section_flags (stdoutput, sec) & SEC_CODE)
+  if (bfd_section_flags (sec) & SEC_CODE)
     off &= ~0xfUL;
 
   return off;
@@ -10812,9 +10996,9 @@ ia64_dwarf2_emit_offset (symbolS *symbol, unsigned int size)
    fixup.  We pick the right reloc code depending on the byteorder
    currently in effect.  */
 void
-ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp)
+ia64_cons_fix_new (fragS *f, int where, int nbytes, expressionS *exp,
+                  bfd_reloc_code_real_type code)
 {
-  bfd_reloc_code_real_type code;
   fixS *fix;
 
   switch (nbytes)
@@ -11109,6 +11293,11 @@ ia64_gen_real_reloc_type (struct symbol *sym, bfd_reloc_code_real_type r_type)
        }
       break;
 
+#ifdef TE_VMS
+    case FUNC_SLOTCOUNT_RELOC:
+      return DUMMY_RELOC_IA64_SLOTCOUNT;
+#endif
+
     default:
       abort ();
     }
@@ -11255,7 +11444,7 @@ md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
     }
   if (fix->fx_addsy)
     {
-      switch (fix->fx_r_type)
+      switch ((unsigned) fix->fx_r_type)
        {
        case BFD_RELOC_UNUSED:
          /* This must be a TAG13 or TAG13b operand.  There are no external
@@ -11278,12 +11467,48 @@ md_apply_fix (fixS *fix, valueT *valP, segT seg ATTRIBUTE_UNUSED)
          S_SET_THREAD_LOCAL (fix->fx_addsy);
          break;
 
+#ifdef TE_VMS
+        case DUMMY_RELOC_IA64_SLOTCOUNT:
+         as_bad_where (fix->fx_file, fix->fx_line,
+                       _("cannot resolve @slotcount parameter"));
+         fix->fx_done = 1;
+         return;
+#endif
+
        default:
          break;
        }
     }
   else if (fix->tc_fix_data.opnd == IA64_OPND_NIL)
     {
+#ifdef TE_VMS
+      if (fix->fx_r_type == DUMMY_RELOC_IA64_SLOTCOUNT)
+        {
+          /* For @slotcount, convert an addresses difference to a slots
+             difference.  */
+          valueT v;
+
+          v = (value >> 4) * 3;
+          switch (value & 0x0f)
+            {
+            case 0:
+            case 1:
+            case 2:
+              v += value & 0x0f;
+              break;
+            case 0x0f:
+              v += 2;
+              break;
+            case 0x0e:
+              v += 1;
+              break;
+            default:
+              as_bad (_("invalid @slotcount value"));
+            }
+          value = v;
+        }
+#endif
+
       if (fix->tc_fix_data.bigendian)
        number_to_chars_bigendian (fixpos, value, fix->fx_size);
       else
@@ -11305,8 +11530,8 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp)
 {
   arelent *reloc;
 
-  reloc = xmalloc (sizeof (*reloc));
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  reloc = XNEW (arelent);
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
   reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
   reloc->addend = fixp->fx_offset;
@@ -11328,9 +11553,7 @@ tc_gen_reloc (asection *sec ATTRIBUTE_UNUSED, fixS *fixp)
    of LITTLENUMS emitted is stored in *SIZE.  An error message is
    returned, or NULL on OK.  */
 
-#define MAX_LITTLENUMS 5
-
-char *
+const char *
 md_atof (int type, char *lit, int *size)
 {
   LITTLENUM_TYPE words[MAX_LITTLENUMS];
@@ -11414,7 +11637,7 @@ ia64_handle_align (fragS *fragp)
   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
   p = fragp->fr_literal + fragp->fr_fix;
 
-  /* If no paddings are needed, we check if we need a stop bit.  */ 
+  /* If no paddings are needed, we check if we need a stop bit.  */
   if (!bytes && fragp->tc_frag_data)
     {
       if (fragp->fr_fix < 16)
@@ -11499,7 +11722,7 @@ ia64_check_label (symbolS *label)
    the relocatable file.  */
 struct alias
 {
-  char *file;          /* The file where the directive is seen.  */
+  const char *file;            /* The file where the directive is seen.  */
   unsigned int line;   /* The line number the directive is at.  */
   const char *name;    /* The original name of the symbol.  */
 };
@@ -11513,14 +11736,12 @@ dot_alias (int section)
   char delim;
   char *end_name;
   int len;
-  const char *error_string;
   struct alias *h;
   const char *a;
-  struct hash_control *ahash, *nhash;
+  htab_t ahash, nhash;
   const char *kind;
 
-  name = input_line_pointer;
-  delim = get_symbol_end ();
+  delim = get_symbol_name (&name);
   end_name = input_line_pointer;
   *end_name = delim;
 
@@ -11531,7 +11752,7 @@ dot_alias (int section)
       return;
     }
 
-  SKIP_WHITESPACE ();
+  SKIP_WHITESPACE_AFTER_NAME ();
 
   if (*input_line_pointer != ',')
     {
@@ -11574,54 +11795,46 @@ dot_alias (int section)
     }
 
   /* Check if alias has been used before.  */
-  h = (struct alias *) hash_find (ahash, alias);
+
+  h = (struct alias *) str_hash_find (ahash, alias);
   if (h)
     {
       if (strcmp (h->name, name))
        as_bad (_("`%s' is already the alias of %s `%s'"),
                alias, kind, h->name);
+      obstack_free (&notes, name);
+      obstack_free (&notes, alias);
       goto out;
     }
 
   /* Check if name already has an alias.  */
-  a = (const char *) hash_find (nhash, name);
+  a = (const char *) str_hash_find (nhash, name);
   if (a)
     {
       if (strcmp (a, alias))
        as_bad (_("%s `%s' already has an alias `%s'"), kind, name, a);
+      obstack_free (&notes, name);
+      obstack_free (&notes, alias);
       goto out;
     }
 
-  h = (struct alias *) xmalloc (sizeof (struct alias));
-  as_where (&h->file, &h->line);
+  h = XNEW (struct alias);
+  h->file = as_where (&h->line);
   h->name = name;
-  
-  error_string = hash_jam (ahash, alias, (void *) h);
-  if (error_string)
-    {
-      as_fatal (_("inserting \"%s\" into %s alias hash table failed: %s"),
-               alias, kind, error_string);
-      goto out;
-    }
 
-  error_string = hash_jam (nhash, name, (void *) alias);
-  if (error_string)
-    {
-      as_fatal (_("inserting \"%s\" into %s name hash table failed: %s"),
-               alias, kind, error_string);
-out:
-      obstack_free (&notes, name);
-      obstack_free (&notes, alias);
-    }
+  str_hash_insert (ahash, alias, h, 0);
+  str_hash_insert (nhash, name, alias, 0);
 
+out:
   demand_empty_rest_of_line ();
 }
 
 /* It renames the original symbol name to its alias.  */
-static void
-do_alias (const char *alias, void *value)
+static int
+do_alias (void **slot, void *arg ATTRIBUTE_UNUSED)
 {
-  struct alias *h = (struct alias *) value;
+  string_tuple_t *tuple = *((string_tuple_t **) slot);
+  struct alias *h = (struct alias *) tuple->value;
   symbolS *sym = symbol_find (h->name);
 
   if (sym == NULL)
@@ -11630,43 +11843,48 @@ do_alias (const char *alias, void *value)
       /* Uses .alias extensively to alias CRTL functions to same with
         decc$ prefix. Sometimes function gets optimized away and a
         warning results, which should be suppressed.  */
-      if (strncmp (alias, "decc$", 5) != 0)
+      if (strncmp (tuple->key, "decc$", 5) != 0)
 #endif
        as_warn_where (h->file, h->line,
                       _("symbol `%s' aliased to `%s' is not used"),
-                      h->name, alias);
+                      h->name, tuple->key);
     }
     else
-      S_SET_NAME (sym, (char *) alias);
+      S_SET_NAME (sym, (char *) tuple->key);
+
+  return 1;
 }
 
 /* Called from write_object_file.  */
 void
 ia64_adjust_symtab (void)
 {
-  hash_traverse (alias_hash, do_alias);
+  htab_traverse (alias_hash, do_alias, NULL);
 }
 
 /* It renames the original section name to its alias.  */
-static void
-do_secalias (const char *alias, void *value)
+static int
+do_secalias (void **slot, void *arg ATTRIBUTE_UNUSED)
 {
-  struct alias *h = (struct alias *) value;
+  string_tuple_t *tuple = *((string_tuple_t **) slot);
+  struct alias *h = (struct alias *) tuple->value;
   segT sec = bfd_get_section_by_name (stdoutput, h->name);
 
   if (sec == NULL)
     as_warn_where (h->file, h->line,
                   _("section `%s' aliased to `%s' is not used"),
-                  h->name, alias);
+                  h->name, tuple->key);
   else
-    sec->name = alias;
+    sec->name = tuple->key;
+
+  return 1;
 }
 
 /* Called from write_object_file.  */
 void
 ia64_frob_file (void)
 {
-  hash_traverse (secalias_hash, do_secalias);
+  htab_traverse (secalias_hash, do_secalias, NULL);
 }
 
 #ifdef TE_VMS
@@ -11699,7 +11917,6 @@ ia64_vms_note (void)
   char *p;
   asection *seg = now_seg;
   subsegT subseg = now_subseg;
-  Elf_Internal_Note i_note;
   asection *secp = NULL;
   char *bname;
   char buf [256];
@@ -11708,43 +11925,29 @@ ia64_vms_note (void)
   /* Create the .note section.  */
 
   secp = subseg_new (".note", 0);
-  bfd_set_section_flags (stdoutput,
-                        secp,
-                        SEC_HAS_CONTENTS | SEC_READONLY);
+  bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY);
 
-  /* Module header note.  */
+  /* Module header note (MHD).  */
   bname = xstrdup (lbasename (out_file_name));
   if ((p = strrchr (bname, '.')))
     *p = '\0';
 
-  i_note.namesz = 8;
-  i_note.descsz = 40 + strlen (bname);
-  i_note.type = NT_VMS_MHD;
-
-  p = frag_more (sizeof (i_note.namesz));
-  number_to_chars_littleendian (p, i_note.namesz, 8);
-
-  p = frag_more (sizeof (i_note.descsz));
-  number_to_chars_littleendian (p, i_note.descsz, 8);
-
-  p = frag_more (sizeof (i_note.type));
-  number_to_chars_littleendian (p, i_note.type, 8);
+  /* VMS note header is 24 bytes long.  */
+  p = frag_more (8 + 8 + 8);
+  number_to_chars_littleendian (p + 0, 8, 8);
+  number_to_chars_littleendian (p + 8, 40 + strlen (bname), 8);
+  number_to_chars_littleendian (p + 16, NT_VMS_MHD, 8);
 
   p = frag_more (8);
   strcpy (p, "IPF/VMS");
 
-  get_vms_time (buf);
-  p = frag_more (17);
-  strcpy (p, buf);
-
-  p = frag_more (17);
-  strcpy (p, "24-FEB-2005 15:00");
-
-  p = frag_more (strlen (bname) + 1);
+  p = frag_more (17 + 17 + strlen (bname) + 1 + 5);
+  get_vms_time (p);
+  strcpy (p + 17, "24-FEB-2005 15:00");
+  p += 17 + 17;
   strcpy (p, bname);
+  p += strlen (bname) + 1;
   free (bname);
-
-  p = frag_more (5);
   strcpy (p, "V1.0");
 
   frag_align (3, 0, 0);
@@ -11753,18 +11956,10 @@ ia64_vms_note (void)
   sprintf (buf, "GNU assembler version %s (%s) using BFD version %s",
           VERSION, TARGET_ALIAS, BFD_VERSION_STRING);
 
-  i_note.namesz = 8;
-  i_note.descsz = 1 + strlen (buf);
-  i_note.type = NT_VMS_LNM;
-
-  p = frag_more (sizeof (i_note.namesz));
-  number_to_chars_littleendian (p, i_note.namesz, 8);
-
-  p = frag_more (sizeof (i_note.descsz));
-  number_to_chars_littleendian (p, i_note.descsz, 8);
-
-  p = frag_more (sizeof (i_note.type));
-  number_to_chars_littleendian (p, i_note.type, 8);
+  p = frag_more (8 + 8 + 8);
+  number_to_chars_littleendian (p + 0, 8, 8);
+  number_to_chars_littleendian (p + 8, strlen (buf) + 1, 8);
+  number_to_chars_littleendian (p + 16, NT_VMS_LNM, 8);
 
   p = frag_more (8);
   strcpy (p, "IPF/VMS");
@@ -11775,14 +11970,12 @@ ia64_vms_note (void)
   frag_align (3, 0, 0);
 
   secp = subseg_new (".vms_display_name_info", 0);
-  bfd_set_section_flags (stdoutput,
-                        secp,
-                        SEC_HAS_CONTENTS | SEC_READONLY);
+  bfd_set_section_flags (secp, SEC_HAS_CONTENTS | SEC_READONLY);
 
   /* This symbol should be passed on the command line and be variable
      according to language.  */
   sym = symbol_new ("__gnat_vms_display_name@gnat_demangler_rtl",
-                   absolute_section, 0, &zero_address_frag);
+                   absolute_section, &zero_address_frag, 0);
   symbol_table_insert (sym);
   symbol_get_bfdsym (sym)->flags |= BSF_DEBUGGING | BSF_DYNAMIC;