bfd_section_* macros
[deliverable/binutils-gdb.git] / gas / config / tc-hppa.c
index 7bb7966141f1dd9daa16e675add61073db8fcb29..fb6d82bc596072d42892d6c01275b1107afc4f70 100644 (file)
@@ -1,6 +1,5 @@
 /* tc-hppa.c -- Assemble for the PA
-   Copyright 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
-   2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+   Copyright (C) 1989-2019 Free Software Foundation, Inc.
 
    This file is part of GAS, the GNU Assembler.
 
@@ -351,7 +350,7 @@ typedef struct space_dictionary_chain sd_chain_struct;
 struct default_subspace_dict
   {
     /* Name of the subspace.  */
-    char *name;
+    const char *name;
 
     /* FIXME.  Is this still needed?  */
     char defined;
@@ -404,7 +403,7 @@ struct default_subspace_dict
 struct default_space_dict
   {
     /* Name of the space.  */
-    char *name;
+    const char *name;
 
     /* Space number.  It is possible to identify spaces within
        assembly code numerically!  */
@@ -466,7 +465,7 @@ struct hppa_fix_struct
 
 struct pd_reg
   {
-    char *name;
+    const char *name;
     int value;
   };
 
@@ -474,7 +473,7 @@ struct pd_reg
    to a condition number which can be recorded in an instruction.  */
 struct fp_cond_map
   {
-    char *string;
+    const char *string;
     int cond;
   };
 
@@ -482,7 +481,7 @@ struct fp_cond_map
    string to a field selector type.  */
 struct selector_entry
   {
-    char *prefix;
+    const char *prefix;
     int field_selector;
   };
 
@@ -504,27 +503,27 @@ static void pa_align (int);
 static void pa_space (int);
 static void pa_spnum (int);
 static void pa_subspace (int);
-static sd_chain_struct *create_new_space (char *, int, int,
-                                                 int, int, int,
-                                                 asection *, int);
+static sd_chain_struct *create_new_space (const char *, int, int,
+                                         int, int, int,
+                                         asection *, int);
 static ssd_chain_struct *create_new_subspace (sd_chain_struct *,
-                                                     char *, int, int,
-                                                     int, int, int, int,
-                                                     int, int, int, int,
-                                                     int, asection *);
+                                             const char *, int, int,
+                                             int, int, int, int,
+                                             int, int, int, int,
+                                             int, asection *);
 static ssd_chain_struct *update_subspace (sd_chain_struct *,
-                                                 char *, int, int, int,
-                                                 int, int, int, int,
-                                                 int, int, int, int,
-                                                 asection *);
-static sd_chain_struct *is_defined_space (char *);
-static ssd_chain_struct *is_defined_subspace (char *);
+                                         char *, int, int, int,
+                                         int, int, int, int,
+                                         int, int, int, int,
+                                         asection *);
+static sd_chain_struct *is_defined_space (const char *);
+static ssd_chain_struct *is_defined_subspace (const char *);
 static sd_chain_struct *pa_segment_to_space (asection *);
 static ssd_chain_struct *pa_subsegment_to_subspace (asection *,
                                                            subsegT);
 static sd_chain_struct *pa_find_space_by_number (int);
 static unsigned int pa_subspace_start (sd_chain_struct *, int);
-static sd_chain_struct *pa_parse_space_stmt (char *, int);
+static sd_chain_struct *pa_parse_space_stmt (const char *, int);
 #endif
 
 /* File and globally scoped variable declarations.  */
@@ -607,8 +606,8 @@ static int within_procedure;
    seen in each subspace.  */
 static label_symbol_struct *label_symbols_rootp = NULL;
 
-/* Holds the last field selector.  */
-static int hppa_field_selector;
+/* Last label symbol */
+static label_symbol_struct last_label_symbol;
 
 /* Nonzero when strict matching is enabled.  Zero otherwise.
 
@@ -995,6 +994,19 @@ static struct default_space_dict pa_def_spaces[] =
 #define IS_R_SELECT(S)   (*(S) == 'R' || *(S) == 'r')
 #define IS_L_SELECT(S)   (*(S) == 'L' || *(S) == 'l')
 
+/* Store immediate values of shift/deposit/extract functions.  */
+
+#define SAVE_IMMEDIATE(VALUE) \
+  { \
+    if (immediate_check) \
+      { \
+       if (pos == -1) \
+         pos = (VALUE); \
+       else if (len == -1) \
+         len = (VALUE); \
+      } \
+  }
+
 /* Insert FIELD into OPCODE starting at bit START.  Continue pa_ip
    main loop after insertion.  */
 
@@ -1105,19 +1117,17 @@ pa_check_eof (void)
 static label_symbol_struct *
 pa_get_label (void)
 {
-  label_symbol_struct *label_chain;
+  label_symbol_struct *label_chain = label_symbols_rootp;
 
-  for (label_chain = label_symbols_rootp;
-       label_chain;
-       label_chain = label_chain->lss_next)
+  if (label_chain)
     {
 #ifdef OBJ_SOM
-    if (current_space == label_chain->lss_space && label_chain->lss_label)
-      return label_chain;
+      if (current_space == label_chain->lss_space && label_chain->lss_label)
+       return label_chain;
 #endif
 #ifdef OBJ_ELF
-    if (now_seg == label_chain->lss_segment && label_chain->lss_label)
-      return label_chain;
+      if (now_seg == label_chain->lss_segment && label_chain->lss_label)
+       return label_chain;
 #endif
     }
 
@@ -1130,28 +1140,23 @@ pa_get_label (void)
 void
 pa_define_label (symbolS *symbol)
 {
-  label_symbol_struct *label_chain = pa_get_label ();
+  label_symbol_struct *label_chain = label_symbols_rootp;
 
-  if (label_chain)
-    label_chain->lss_label = symbol;
-  else
-    {
-      /* Create a new label entry and add it to the head of the chain.  */
-      label_chain = xmalloc (sizeof (label_symbol_struct));
-      label_chain->lss_label = symbol;
+  if (!label_chain)
+    label_chain = &last_label_symbol;
+
+  label_chain->lss_label = symbol;
 #ifdef OBJ_SOM
-      label_chain->lss_space = current_space;
+  label_chain->lss_space = current_space;
 #endif
 #ifdef OBJ_ELF
-      label_chain->lss_segment = now_seg;
+  label_chain->lss_segment = now_seg;
 #endif
-      label_chain->lss_next = NULL;
 
-      if (label_symbols_rootp)
-       label_chain->lss_next = label_symbols_rootp;
+  /* Not used.  */
+  label_chain->lss_next = NULL;
 
-      label_symbols_rootp = label_chain;
-    }
+  label_symbols_rootp = label_chain;
 
 #ifdef OBJ_ELF
   dwarf2_emit_label (symbol);
@@ -1164,33 +1169,7 @@ pa_define_label (symbolS *symbol)
 static void
 pa_undefine_label (void)
 {
-  label_symbol_struct *label_chain;
-  label_symbol_struct *prev_label_chain = NULL;
-
-  for (label_chain = label_symbols_rootp;
-       label_chain;
-       label_chain = label_chain->lss_next)
-    {
-      if (1
-#ifdef OBJ_SOM
-         && current_space == label_chain->lss_space && label_chain->lss_label
-#endif
-#ifdef OBJ_ELF
-         && now_seg == label_chain->lss_segment && label_chain->lss_label
-#endif
-         )
-       {
-         /* Remove the label from the chain and free its memory.  */
-         if (prev_label_chain)
-           prev_label_chain->lss_next = label_chain->lss_next;
-         else
-           label_symbols_rootp = label_chain->lss_next;
-
-         free (label_chain);
-         break;
-       }
-      prev_label_chain = label_chain;
-    }
+  label_symbols_rootp = NULL;
 }
 
 /* An HPPA-specific version of fix_new.  This is required because the HPPA
@@ -1215,7 +1194,7 @@ fix_new_hppa (fragS *frag,
              int unwind_bits ATTRIBUTE_UNUSED)
 {
   fixS *new_fix;
-  struct hppa_fix_struct *hppa_fix = obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
+  struct hppa_fix_struct *hppa_fix = XOBNEW (&notes, struct hppa_fix_struct);
 
   if (exp != NULL)
     new_fix = fix_new_exp (frag, where, size, exp, pcrel, r_type);
@@ -1251,7 +1230,8 @@ fix_new_hppa (fragS *frag,
    hppa_field_selector is set by the parse_cons_expression_hppa.  */
 
 void
-cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
+cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp,
+                  int hppa_field_selector)
 {
   unsigned int rel_type;
 
@@ -1288,9 +1268,6 @@ cons_fix_new_hppa (fragS *frag, int where, int size, expressionS *exp)
   fix_new_hppa (frag, where, size,
                (symbolS *) NULL, (offsetT) 0, exp, 0, rel_type,
                hppa_field_selector, size * 8, 0, 0);
-
-  /* Reset field selector to its default state.  */
-  hppa_field_selector = 0;
 }
 
 /* Mark (via expr_end) the end of an expression (I think).  FIXME.  */
@@ -1342,7 +1319,7 @@ pa_parse_nullif (char **s)
   return nullif;
 }
 
-char *
+const char *
 md_atof (int type, char *litP, int *sizeP)
 {
   return ieee_md_atof (type, litP, sizeP, TRUE);
@@ -1375,12 +1352,12 @@ tc_gen_reloc (asection *section, fixS *fixp)
   if (fixp->fx_addsy == 0)
     return &no_relocs;
 
-  assert (hppa_fixp != 0);
-  assert (section != 0);
+  gas_assert (hppa_fixp != 0);
+  gas_assert (section != 0);
 
-  reloc = xmalloc (sizeof (arelent));
+  reloc = XNEW (arelent);
 
-  reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+  reloc->sym_ptr_ptr = XNEW (asymbol *);
   *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
 
   /* Allow fixup_segment to recognize hand-written pc-relative relocations.
@@ -1388,7 +1365,8 @@ tc_gen_reloc (asection *section, fixS *fixp)
   /* ??? It might be better to hide this +8 stuff in tc_cfi_emit_pcrel_expr,
      undefine DIFF_EXPR_OK, and let these sorts of complex expressions fail
      when R_HPPA_COMPLEX == R_PARISC_UNIMPLEMENTED.  */
-  if (fixp->fx_r_type == R_HPPA_COMPLEX && fixp->fx_pcrel)
+  if (fixp->fx_r_type == (bfd_reloc_code_real_type) R_HPPA_COMPLEX
+      && fixp->fx_pcrel)
     {
       fixp->fx_r_type = R_HPPA_PCREL_CALL;
       fixp->fx_offset += 8;
@@ -1410,8 +1388,8 @@ tc_gen_reloc (asection *section, fixS *fixp)
   for (n_relocs = 0; codes[n_relocs]; n_relocs++)
     ;
 
-  relocs = xmalloc (sizeof (arelent *) * n_relocs + 1);
-  reloc = xmalloc (sizeof (arelent) * n_relocs);
+  relocs = XNEWVEC (arelent *, n_relocs + 1);
+  reloc = XNEWVEC (arelent, n_relocs);
   for (i = 0; i < n_relocs; i++)
     relocs[i] = &reloc[i];
 
@@ -1421,7 +1399,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
   switch (fixp->fx_r_type)
     {
     default:
-      assert (n_relocs == 1);
+      gas_assert (n_relocs == 1);
 
       code = *codes[0];
 
@@ -1462,20 +1440,20 @@ tc_gen_reloc (asection *section, fixS *fixp)
          /* Facilitate hand-crafted unwind info.  */
          if (strcmp (section->name, UNWIND_SECTION_NAME) == 0)
            code = R_PARISC_SEGREL32;
-         /* Fall thru */
+         /* Fallthru */
 
        default:
          reloc->addend = fixp->fx_offset;
          break;
        }
 
-      reloc->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+      reloc->sym_ptr_ptr = XNEW (asymbol *);
       *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
       reloc->howto = bfd_reloc_type_lookup (stdoutput,
                                            (bfd_reloc_code_real_type) code);
       reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
 
-      assert (reloc->howto && (unsigned int) code == reloc->howto->type);
+      gas_assert (reloc->howto && (unsigned int) code == reloc->howto->type);
       break;
     }
 #else /* OBJ_SOM */
@@ -1485,7 +1463,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
     {
       code = *codes[i];
 
-      relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+      relocs[i]->sym_ptr_ptr = XNEW (asymbol *);
       *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
       relocs[i]->howto =
        bfd_reloc_type_lookup (stdoutput,
@@ -1498,7 +1476,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
          /* The only time we ever use a R_COMP2 fixup is for the difference
             of two symbols.  With that in mind we fill in all four
             relocs now and break out of the loop.  */
-         assert (i == 1);
+         gas_assert (i == 1);
          relocs[0]->sym_ptr_ptr
            = (asymbol **) bfd_abs_section_ptr->symbol_ptr_ptr;
          relocs[0]->howto
@@ -1506,14 +1484,14 @@ tc_gen_reloc (asection *section, fixS *fixp)
                                     (bfd_reloc_code_real_type) *codes[0]);
          relocs[0]->address = fixp->fx_frag->fr_address + fixp->fx_where;
          relocs[0]->addend = 0;
-         relocs[1]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+         relocs[1]->sym_ptr_ptr = XNEW (asymbol *);
          *relocs[1]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
          relocs[1]->howto
            = bfd_reloc_type_lookup (stdoutput,
                                     (bfd_reloc_code_real_type) *codes[1]);
          relocs[1]->address = fixp->fx_frag->fr_address + fixp->fx_where;
          relocs[1]->addend = 0;
-         relocs[2]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+         relocs[2]->sym_ptr_ptr = XNEW (asymbol *);
          *relocs[2]->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy);
          relocs[2]->howto
            = bfd_reloc_type_lookup (stdoutput,
@@ -1568,7 +1546,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
        case R_N0SEL:
        case R_N1SEL:
          /* There is no symbol or addend associated with these fixups.  */
-         relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+         relocs[i]->sym_ptr_ptr = XNEW (asymbol *);
          *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
          relocs[i]->addend = 0;
          break;
@@ -1577,7 +1555,7 @@ tc_gen_reloc (asection *section, fixS *fixp)
        case R_ENTRY:
        case R_EXIT:
          /* There is no symbol associated with these fixups.  */
-         relocs[i]->sym_ptr_ptr = xmalloc (sizeof (asymbol *));
+         relocs[i]->sym_ptr_ptr = XNEW (asymbol *);
          *relocs[i]->sym_ptr_ptr = symbol_get_bfdsym (dummy_symbol);
          relocs[i]->addend = fixp->fx_offset;
          break;
@@ -1630,7 +1608,7 @@ md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
 valueT
 md_section_align (asection *segment, valueT size)
 {
-  int align = bfd_get_section_alignment (stdoutput, segment);
+  int align = bfd_section_alignment (segment);
   int align2 = (1 << align) - 1;
 
   return (size + align2) & ~align2;
@@ -1675,7 +1653,7 @@ struct option md_longopts[] =
 size_t md_longopts_size = sizeof (md_longopts);
 
 int
-md_parse_option (int c, char *arg ATTRIBUTE_UNUSED)
+md_parse_option (int c, const char *arg ATTRIBUTE_UNUSED)
 {
   switch (c)
     {
@@ -2192,7 +2170,7 @@ pa_parse_number (char **s, int is_float)
                 register, so...  */
              have_prefix = TRUE;
            }
-         else if (S_GET_SEGMENT (sym) == &bfd_abs_section)
+         else if (S_GET_SEGMENT (sym) == bfd_abs_section_ptr)
            num = S_GET_VALUE (sym);
          else if (!strict)
            {
@@ -2504,11 +2482,12 @@ pa_chk_field_selector (char **str)
 /* Parse a .byte, .word, .long expression for the HPPA.  Called by
    cons via the TC_PARSE_CONS_EXPRESSION macro.  */
 
-void
+int
 parse_cons_expression_hppa (expressionS *exp)
 {
-  hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
+  int hppa_field_selector = pa_chk_field_selector (&input_line_pointer);
   expression (exp);
+  return hppa_field_selector;
 }
 
 /* Evaluate an absolute expression EXP which may be modified by
@@ -2537,51 +2516,54 @@ pa_get_absolute_expression (struct pa_it *insn, char **strp)
   save_in = input_line_pointer;
   input_line_pointer = *strp;
   expression (&insn->exp);
-  /* This is not perfect, but is a huge improvement over doing nothing.
+  expr_end = input_line_pointer;
+  input_line_pointer = save_in;
+  if (insn->exp.X_op != O_constant)
+    {
+      /* We have a non-match in strict mode.  */
+      if (!strict)
+       as_bad (_("Bad segment (should be absolute)."));
+      return 0;
+    }
+  return evaluate_absolute (insn);
+}
+
+/* Get an absolute number.  The input string is terminated at the
+   first whitespace character.  */
 
-     The PA assembly syntax is ambiguous in a variety of ways.  Consider
+static int
+pa_get_number (struct pa_it *insn, char **strp)
+{
+  char *save_in;
+  char *s, c;
+  int result;
+
+  save_in = input_line_pointer;
+  input_line_pointer = *strp;
+
+  /* The PA assembly syntax is ambiguous in a variety of ways.  Consider
      this string "4 %r5"  Is that the number 4 followed by the register
-     r5, or is that 4 MOD r5?
+     r5, or is that 4 MOD r5?  This situation occurs for example in the
+     coprocessor load and store instructions.  Previously, calling
+     pa_get_absolute_expression directly results in r5 being entered
+     in the symbol table.
 
-     If we get a modulo expression when looking for an absolute, we try
-     again cutting off the input string at the first whitespace character.  */
-  if (insn->exp.X_op == O_modulus)
-    {
-      char *s, c;
-      int retval;
+     So, when looking for an absolute number, we cut off the input string
+     at the first whitespace character.  Thus, expressions should generally
+     contain no whitespace.  */
 
-      input_line_pointer = *strp;
-      s = *strp;
-      while (*s != ',' && *s != ' ' && *s != '\t')
-       s++;
+  s = *strp;
+  while (*s != ',' && *s != ' ' && *s != '\t')
+    s++;
 
-      c = *s;
-      *s = 0;
+  c = *s;
+  *s = 0;
 
-      retval = pa_get_absolute_expression (insn, strp);
+  result = pa_get_absolute_expression (insn, strp);
 
-      input_line_pointer = save_in;
-      *s = c;
-      return evaluate_absolute (insn);
-    }
-  /* When in strict mode we have a non-match, fix up the pointers
-     and return to our caller.  */
-  if (insn->exp.X_op != O_constant && strict)
-    {
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  if (insn->exp.X_op != O_constant)
-    {
-      as_bad (_("Bad segment (should be absolute)."));
-      expr_end = input_line_pointer;
-      input_line_pointer = save_in;
-      return 0;
-    }
-  expr_end = input_line_pointer;
   input_line_pointer = save_in;
-  return evaluate_absolute (insn);
+  *s = c;
+  return result;
 }
 
 /* Given an argument location specification return the associated
@@ -3185,12 +3167,13 @@ pa_parse_addb_64_cmpltr (char **s)
 static void
 pa_ip (char *str)
 {
-  char *error_message = "";
+  const char *error_message = "";
   char *s, c, *argstart, *name, *save_s;
   const char *args;
   int match = FALSE;
   int comma = 0;
-  int cmpltr, nullif, flag, cond, num;
+  int cmpltr, nullif, flag, cond, need_cond, num;
+  int immediate_check = 0, pos = -1, len = -1;
   unsigned long opcode;
   struct pa_opcode *insn;
 
@@ -3233,7 +3216,7 @@ pa_ip (char *str)
   /* Look up the opcode in the hash table.  */
   if ((insn = (struct pa_opcode *) hash_find (op_hash, str)) == NULL)
     {
-      as_bad ("Unknown opcode: `%s'", str);
+      as_bad (_("Unknown opcode: `%s'"), str);
       return;
     }
 
@@ -3249,6 +3232,7 @@ pa_ip (char *str)
       opcode = insn->match;
       strict = (insn->flags & FLAG_STRICT);
       memset (&the_insn, 0, sizeof (the_insn));
+      need_cond = 1;
 
       the_insn.reloc = R_HPPA_NONE;
 
@@ -3351,6 +3335,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 32, 1, 0);
+             SAVE_IMMEDIATE(num);
              INSERT_FIELD_AND_CONTINUE (opcode, 32 - num, 0);
 
            /* Handle a 5 bit immediate at 15.  */
@@ -3520,8 +3505,9 @@ pa_ip (char *str)
                        /* M bit is explicit in the major opcode.  */
                        INSERT_FIELD_AND_CONTINUE (opcode, a, 2);
                      }
-                   else if (*args == 'e')
+                   else
                      {
+                       gas_assert (*args == 'e');
                        /* Stash the ma/mb flag temporarily in the
                           instruction.  We will use (and remove it)
                           later when handling 'J', 'K', '<' & '>'.  */
@@ -3742,6 +3728,8 @@ pa_ip (char *str)
                  else
                    break;
 
+                 /* Condition is not required with "dc".  */
+                 need_cond = 0;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
 
                /* Handle 32 bit carry for ADD.  */
@@ -3810,6 +3798,8 @@ pa_ip (char *str)
                  else
                    break;
 
+                 /* Condition is not required with "db".  */
+                 need_cond = 0;
                  INSERT_FIELD_AND_CONTINUE (opcode, flag, 11);
 
                /* Handle 32 bit borrow for SUB.  */
@@ -4035,6 +4025,11 @@ pa_ip (char *str)
                          as_bad (_("Invalid Add Condition: %s"), name);
                        *s = c;
                      }
+                   /* Except with "dc", we have a match failure with
+                      'A' if we don't have a doubleword condition.  */
+                   else if (*args == 'A' && need_cond)
+                     break;
+
                    opcode |= cmpltr << 13;
                    INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
 
@@ -4114,8 +4109,11 @@ pa_ip (char *str)
                            s += 2;
                          }
                        else
-                         as_bad (_("Invalid Bit Branch Condition: %c"), *s);
+                         as_bad (_("Invalid Branch On Bit Condition: %c"), *s);
                      }
+                   else
+                     as_bad (_("Missing Branch On Bit Condition"));
+
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 15);
 
                  /* Handle a compare/subtract condition.  */
@@ -4203,6 +4201,11 @@ pa_ip (char *str)
                                  name);
                        *s = c;
                      }
+                   /* Except with "db", we have a match failure with
+                      'S' if we don't have a doubleword condition.  */
+                   else if (*args == 'S' && need_cond)
+                     break;
+
                    opcode |= cmpltr << 13;
                    INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
 
@@ -4261,7 +4264,7 @@ pa_ip (char *str)
 
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
 
-                   /* Handle a logical instruction condition.  */
+                 /* Handle a logical instruction condition.  */
                  case 'L':
                  case 'l':
                    cmpltr = 0;
@@ -4325,6 +4328,10 @@ pa_ip (char *str)
                          as_bad (_("Invalid Logical Instruction Condition."));
                        *s = c;
                      }
+                   /* 32-bit is default for no condition.  */
+                   else if (*args == 'L')
+                     break;
+
                    opcode |= cmpltr << 13;
                    INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
 
@@ -4333,6 +4340,9 @@ pa_ip (char *str)
                  case 'x':
                  case 'y':
                    cmpltr = 0;
+                   /* Check immediate values in shift/extract/deposit
+                    * instructions if they will give undefined behaviour.  */
+                   immediate_check = 1;
                    if (*s == ',')
                      {
                        save_s = s++;
@@ -4380,6 +4390,7 @@ pa_ip (char *str)
                          as_bad (_("Invalid Shift/Extract/Deposit Condition."));
                        *s = c;
                      }
+
                    INSERT_FIELD_AND_CONTINUE (opcode, cmpltr, 13);
 
                  /* Handle a unit instruction condition.  */
@@ -4389,6 +4400,7 @@ pa_ip (char *str)
                    flag = 0;
                    if (*s == ',')
                      {
+                       int uxor;
                        s++;
 
                        /* 64 bit conditions.  */
@@ -4402,6 +4414,9 @@ pa_ip (char *str)
                        else if (*s == '*')
                          break;
 
+                       /* The uxor instruction only supports unit conditions
+                          not involving carries.  */
+                       uxor = (opcode & 0xfc000fc0) == 0x08000380;
                        if (strncasecmp (s, "sbz", 3) == 0)
                          {
                            cmpltr = 2;
@@ -4412,17 +4427,17 @@ pa_ip (char *str)
                            cmpltr = 3;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "sdc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "sdc", 3) == 0)
                          {
                            cmpltr = 4;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "sbc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "sbc", 3) == 0)
                          {
                            cmpltr = 6;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "shc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "shc", 3) == 0)
                          {
                            cmpltr = 7;
                            s += 3;
@@ -4445,19 +4460,19 @@ pa_ip (char *str)
                            flag = 1;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "ndc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "ndc", 3) == 0)
                          {
                            cmpltr = 4;
                            flag = 1;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "nbc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "nbc", 3) == 0)
                          {
                            cmpltr = 6;
                            flag = 1;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "nhc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "nhc", 3) == 0)
                          {
                            cmpltr = 7;
                            flag = 1;
@@ -4469,7 +4484,7 @@ pa_ip (char *str)
                            flag = 0;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "swc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "swc", 3) == 0)
                          {
                            cmpltr = 5;
                            flag = 0;
@@ -4481,7 +4496,7 @@ pa_ip (char *str)
                            flag = 1;
                            s += 3;
                          }
-                       else if (strncasecmp (s, "nwc", 3) == 0)
+                       else if (!uxor && strncasecmp (s, "nwc", 3) == 0)
                          {
                            cmpltr = 5;
                            flag = 1;
@@ -4491,6 +4506,10 @@ pa_ip (char *str)
                        else if (*args != 'U' || (*s != ' ' && *s != '\t'))
                          as_bad (_("Invalid Unit Instruction Condition."));
                      }
+                   /* 32-bit is default for no condition.  */
+                   else if (*args == 'U')
+                     break;
+
                    opcode |= cmpltr << 13;
                    INSERT_FIELD_AND_CONTINUE (opcode, flag, 12);
 
@@ -5125,6 +5144,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 31, 0, strict);
+             SAVE_IMMEDIATE(num);
              INSERT_FIELD_AND_CONTINUE (opcode, 31 - num, 5);
 
            /* Handle a 6 bit shift count at 20,22:26.  */
@@ -5134,6 +5154,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 63, 0, strict);
+             SAVE_IMMEDIATE(num);
              num = 63 - num;
              opcode |= (num & 0x20) << 6;
              INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);
@@ -5146,6 +5167,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 64, 1, strict);
+             SAVE_IMMEDIATE(num);
              num--;
              opcode |= (num & 0x20) << 3;
              num = 31 - (num & 0x1f);
@@ -5158,6 +5180,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 64, 1, strict);
+             SAVE_IMMEDIATE(num);
              num--;
              opcode |= (num & 0x20) << 7;
              num = 31 - (num & 0x1f);
@@ -5170,6 +5193,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 31, 0, strict);
+             SAVE_IMMEDIATE(num);
              INSERT_FIELD_AND_CONTINUE (opcode, num, 5);
 
            /* Handle a 6 bit bit position at 20,22:26.  */
@@ -5179,6 +5203,7 @@ pa_ip (char *str)
                break;
              s = expr_end;
              CHECK_FIELD (num, 63, 0, strict);
+             SAVE_IMMEDIATE(num);
              opcode |= (num & 0x20) << 6;
              INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 5);
 
@@ -5191,9 +5216,7 @@ pa_ip (char *str)
              s = expr_end;
              CHECK_FIELD (num, 63, 0, strict);
              if (num & 0x20)
-               ;
-             else
-               opcode |= (1 << 13);
+               opcode &= ~(1 << 13);
              INSERT_FIELD_AND_CONTINUE (opcode, num & 0x1f, 21);
 
            /* Handle a 5 bit immediate at 10.  */
@@ -5236,7 +5259,7 @@ pa_ip (char *str)
            case 'v':
              if (*s++ != ',')
                as_bad (_("Invalid SFU identifier"));
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5245,7 +5268,7 @@ pa_ip (char *str)
 
            /* Handle a 20 bit SOP field for spop0.  */
            case 'O':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5255,7 +5278,7 @@ pa_ip (char *str)
 
            /* Handle a 15bit SOP field for spop1.  */
            case 'o':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5264,7 +5287,7 @@ pa_ip (char *str)
 
            /* Handle a 10bit SOP field for spop3.  */
            case '0':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5274,7 +5297,7 @@ pa_ip (char *str)
 
            /* Handle a 15 bit SOP field for spop2.  */
            case '1':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5286,7 +5309,7 @@ pa_ip (char *str)
            case 'u':
              if (*s++ != ',')
                as_bad (_("Invalid COPR identifier"));
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5295,7 +5318,7 @@ pa_ip (char *str)
 
            /* Handle a 22bit SOP field for copr.  */
            case '2':
-             num = pa_get_absolute_expression (&the_insn, &s);
+             num = pa_get_number (&the_insn, &s);
              if (strict && the_insn.exp.X_op != O_constant)
                break;
              s = expr_end;
@@ -5407,6 +5430,7 @@ pa_ip (char *str)
                {
                case SGL:
                  opcode |= 0x20;
+                 /* Fall through.  */
                case DBL:
                  the_insn.fpof1 = flag;
                  continue;
@@ -5426,7 +5450,10 @@ pa_ip (char *str)
                case 't':
                  if (!pa_parse_number (&s, 3))
                    break;
-                 num = (pa_number & ~FP_REG_RSEL) - FP_REG_BASE;
+                 /* RSEL should not be set.  */
+                 if (pa_number & FP_REG_RSEL)
+                   break;
+                 num = pa_number - FP_REG_BASE;
                  CHECK_FIELD (num, 31, 0, 0);
                  INSERT_FIELD_AND_CONTINUE (opcode, num, 0);
 
@@ -5658,7 +5685,7 @@ pa_ip (char *str)
       /* If this instruction is specific to a particular architecture,
         then set a new architecture.  This automatic promotion crud is
         for compatibility with HP's old assemblers only.  */
-      if (match == TRUE
+      if (match
          && bfd_get_mach (stdoutput) < insn->arch
          && !bfd_set_arch_mach (stdoutput, bfd_arch_hppa, insn->arch))
        {
@@ -5686,6 +5713,13 @@ pa_ip (char *str)
       break;
     }
 
+  if (immediate_check)
+    {
+      if (pos != -1 && len != -1 && pos < len - 1)
+        as_warn (_("Immediates %d and %d will give undefined behavior."),
+                       pos, len);
+    }
+
   the_insn.opcode = opcode;
 }
 
@@ -5697,7 +5731,7 @@ md_assemble (char *str)
   char *to;
 
   /* The had better be something to assemble.  */
-  assert (str);
+  gas_assert (str);
 
   /* If we are within a procedure definition, make sure we've
      defined a label for the procedure; handle case where the
@@ -5860,33 +5894,28 @@ pa_try (int begin ATTRIBUTE_UNUSED)
 static void
 pa_call_args (struct call_desc *call_desc)
 {
-  char *name, c, *p;
+  char *name, c;
   unsigned int temp, arg_reloc;
 
   while (!is_end_of_statement ())
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       /* Process a source argument.  */
       if ((strncasecmp (name, "argw", 4) == 0))
        {
          temp = atoi (name + 4);
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
-         name = input_line_pointer;
-         c = get_symbol_end ();
+         c = get_symbol_name (&name);
          arg_reloc = pa_build_arg_reloc (name);
          call_desc->arg_reloc |= pa_align_arg_reloc (temp, arg_reloc);
        }
       /* Process a return value.  */
       else if ((strncasecmp (name, "rtnval", 6) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
-         name = input_line_pointer;
-         c = get_symbol_end ();
+         c = get_symbol_name (&name);
          arg_reloc = pa_build_arg_reloc (name);
          call_desc->arg_reloc |= (arg_reloc & 0x3);
        }
@@ -5894,8 +5923,8 @@ pa_call_args (struct call_desc *call_desc)
        {
          as_bad (_("Invalid .CALL argument: %s"), name);
        }
-      p = input_line_pointer;
-      *p = c;
+
+      (void) restore_line_pointer (c);
       if (!is_end_of_statement ())
        input_line_pointer++;
     }
@@ -5930,13 +5959,43 @@ pa_build_unwind_subspace (struct call_info *call_info)
   subsegT save_subseg;
   unsigned int unwind;
   int reloc;
-  char *p;
+  char *name, *p;
+  symbolS *symbolP;
 
-  if ((bfd_get_section_flags (stdoutput, now_seg)
+  if ((bfd_section_flags (now_seg)
        & (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
       != (SEC_ALLOC | SEC_LOAD | SEC_READONLY))
     return;
 
+  if (call_info->start_symbol == NULL)
+    /* This can happen if there were errors earlier on in the assembly.  */
+    return;
+
+  /* Replace the start symbol with a local symbol that will be reduced
+     to a section offset.  This avoids problems with weak functions with
+     multiple definitions, etc.  */
+  name = concat ("L$\001start_", S_GET_NAME (call_info->start_symbol),
+                (char *) NULL);
+
+  /* If we have a .procend preceded by a .exit, then the symbol will have
+     already been defined.  In that case, we don't want another unwind
+     entry.  */
+  symbolP = symbol_find (name);
+  if (symbolP)
+    {
+      xfree (name);
+      return;
+    }
+  else
+    {
+      symbolP = symbol_new (name, now_seg,
+                           S_GET_VALUE (call_info->start_symbol),
+                           symbol_get_frag (call_info->start_symbol));
+      gas_assert (symbolP);
+      S_CLEAR_EXTERNAL (symbolP);
+      symbol_table_insert (symbolP);
+    }
+
   reloc = R_PARISC_SEGREL32;
   save_seg = now_seg;
   save_subseg = now_subseg;
@@ -5947,10 +6006,9 @@ pa_build_unwind_subspace (struct call_info *call_info)
   if (seg == ASEC_NULL)
     {
       seg = subseg_new (UNWIND_SECTION_NAME, 0);
-      bfd_set_section_flags (stdoutput, seg,
-                            SEC_READONLY | SEC_HAS_CONTENTS
-                            | SEC_LOAD | SEC_RELOC | SEC_ALLOC | SEC_DATA);
-      bfd_set_section_alignment (stdoutput, seg, 2);
+      bfd_set_section_flags (seg, (SEC_READONLY | SEC_HAS_CONTENTS | SEC_LOAD
+                                  | SEC_RELOC | SEC_ALLOC | SEC_DATA));
+      bfd_set_section_alignment (seg, 2);
     }
 
   subseg_set (seg, 0);
@@ -5962,7 +6020,7 @@ pa_build_unwind_subspace (struct call_info *call_info)
   /* Relocation info. for start offset of the function.  */
   md_number_to_chars (p, 0, 4);
   fix_new_hppa (frag_now, p - frag_now->fr_literal, 4,
-               call_info->start_symbol, (offsetT) 0,
+               symbolP, (offsetT) 0,
                (expressionS *) NULL, 0, reloc,
                e_fsel, 32, 0, 0);
 
@@ -5998,7 +6056,7 @@ pa_build_unwind_subspace (struct call_info *call_info)
 static void
 pa_callinfo (int unused ATTRIBUTE_UNUSED)
 {
-  char *name, c, *p;
+  char *name, c;
   int temp;
 
 #ifdef OBJ_SOM
@@ -6017,13 +6075,11 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
   /* Iterate over the .CALLINFO arguments.  */
   while (!is_end_of_statement ())
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       /* Frame size specification.  */
       if ((strncasecmp (name, "frame", 5) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = get_absolute_expression ();
          if ((temp & 0x3) != 0)
@@ -6034,13 +6090,11 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
 
          /* callinfo is in bytes and unwind_desc is in 8 byte units.  */
          last_call_info->ci_unwind.descriptor.frame_size = temp / 8;
-
        }
       /* Entry register (GR, GR and SR) specifications.  */
       else if ((strncasecmp (name, "entry_gr", 8) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = get_absolute_expression ();
          /* The HP assembler accepts 19 as the high bound for ENTRY_GR
@@ -6052,8 +6106,7 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
        }
       else if ((strncasecmp (name, "entry_fr", 8) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = get_absolute_expression ();
          /* Similarly the HP assembler takes 31 as the high bound even
@@ -6064,53 +6117,46 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
        }
       else if ((strncasecmp (name, "entry_sr", 8) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = get_absolute_expression ();
          if (temp != 3)
            as_bad (_("Value for ENTRY_SR must be 3\n"));
        }
       /* Note whether or not this function performs any calls.  */
-      else if ((strncasecmp (name, "calls", 5) == 0) ||
-              (strncasecmp (name, "caller", 6) == 0))
+      else if ((strncasecmp (name, "calls", 5) == 0)
+              || (strncasecmp (name, "caller", 6) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
        }
       else if ((strncasecmp (name, "no_calls", 8) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
        }
       /* Should RP be saved into the stack.  */
       else if ((strncasecmp (name, "save_rp", 7) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          last_call_info->ci_unwind.descriptor.save_rp = 1;
        }
       /* Likewise for SP.  */
       else if ((strncasecmp (name, "save_sp", 7) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          last_call_info->ci_unwind.descriptor.save_sp = 1;
        }
       /* Is this an unwindable procedure.  If so mark it so
         in the unwind descriptor.  */
       else if ((strncasecmp (name, "no_unwind", 9) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          last_call_info->ci_unwind.descriptor.cannot_unwind = 1;
        }
       /* Is this an interrupt routine.  If so mark it in the
         unwind descriptor.  */
       else if ((strncasecmp (name, "hpux_int", 7) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          last_call_info->ci_unwind.descriptor.hpux_interrupt_marker = 1;
        }
       /* Is this a millicode routine.  "millicode" isn't in my
@@ -6119,15 +6165,15 @@ pa_callinfo (int unused ATTRIBUTE_UNUSED)
         to drop the information, so we'll accept it too.  */
       else if ((strncasecmp (name, "millicode", 9) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          last_call_info->ci_unwind.descriptor.millicode = 1;
        }
       else
        {
          as_bad (_("Invalid .CALLINFO argument: %s"), name);
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
+
       if (!is_end_of_statement ())
        input_line_pointer++;
     }
@@ -6365,6 +6411,7 @@ hppa_elf_mark_end_of_function (void)
   /* ELF does not have EXIT relocations.  All we do is create a
      temporary symbol marking the end of the function.  */
   char *name;
+  symbolS *symbolP;
 
   if (last_call_info == NULL || last_call_info->start_symbol == NULL)
     {
@@ -6373,48 +6420,37 @@ hppa_elf_mark_end_of_function (void)
       return;
     }
 
-  name = xmalloc (strlen ("L$\001end_")
-                 + strlen (S_GET_NAME (last_call_info->start_symbol))
-                 + 1);
-  if (name)
-    {
-      symbolS *symbolP;
-
-      strcpy (name, "L$\001end_");
-      strcat (name, S_GET_NAME (last_call_info->start_symbol));
+  name = concat ("L$\001end_", S_GET_NAME (last_call_info->start_symbol),
+                (char *) NULL);
 
-      /* If we have a .exit followed by a .procend, then the
-        symbol will have already been defined.  */
-      symbolP = symbol_find (name);
-      if (symbolP)
-       {
-         /* The symbol has already been defined!  This can
-            happen if we have a .exit followed by a .procend.
-
-            This is *not* an error.  All we want to do is free
-            the memory we just allocated for the name and continue.  */
-         xfree (name);
-       }
-      else
-       {
-         /* symbol value should be the offset of the
-            last instruction of the function */
-         symbolP = symbol_new (name, now_seg, (valueT) (frag_now_fix () - 4),
-                               frag_now);
-
-         assert (symbolP);
-         S_CLEAR_EXTERNAL (symbolP);
-         symbol_table_insert (symbolP);
-       }
-
-      if (symbolP)
-       last_call_info->end_symbol = symbolP;
-      else
-       as_bad (_("Symbol '%s' could not be created."), name);
+  /* If we have a .exit followed by a .procend, then the
+     symbol will have already been defined.  */
+  symbolP = symbol_find (name);
+  if (symbolP)
+    {
+      /* The symbol has already been defined!  This can
+        happen if we have a .exit followed by a .procend.
 
+        This is *not* an error.  All we want to do is free
+        the memory we just allocated for the name and continue.  */
+      xfree (name);
     }
   else
-    as_bad (_("No memory for symbol name."));
+    {
+      /* symbol value should be the offset of the
+        last instruction of the function */
+      symbolP = symbol_new (name, now_seg, (valueT) (frag_now_fix () - 4),
+                           frag_now);
+
+      gas_assert (symbolP);
+      S_CLEAR_EXTERNAL (symbolP);
+      symbol_table_insert (symbolP);
+    }
+
+  if (symbolP)
+    last_call_info->end_symbol = symbolP;
+  else
+    as_bad (_("Symbol '%s' could not be created."), name);
 }
 #endif
 
@@ -6433,6 +6469,7 @@ process_exit (void)
   /* Mark the end of the function, stuff away the location of the frag
      for the end of the function, and finally call pa_build_unwind_subspace
      to add an entry in the unwind table.  */
+  (void) where;
   hppa_elf_mark_end_of_function ();
   pa_build_unwind_subspace (last_call_info);
 #else
@@ -6487,7 +6524,7 @@ pa_exit (int unused ATTRIBUTE_UNUSED)
 static void
 pa_type_args (symbolS *symbolP, int is_export)
 {
-  char *name, c, *p;
+  char *name, c;
   unsigned int temp, arg_reloc;
   pa_symbol_type type = SYMBOL_TYPE_UNKNOWN;
   asymbol *bfdsym = symbol_get_bfdsym (symbolP);
@@ -6574,6 +6611,8 @@ pa_type_args (symbolS *symbolP, int is_export)
      to the SOM BFD backend.  */
 #ifdef obj_set_symbol_type
   obj_set_symbol_type (bfdsym, (int) type);
+#else
+  (void) type;
 #endif
 
   /* Now that the type of the exported symbol has been handled,
@@ -6582,56 +6621,56 @@ pa_type_args (symbolS *symbolP, int is_export)
     {
       if (*input_line_pointer == ',')
        input_line_pointer++;
-      name = input_line_pointer;
-      c = get_symbol_end ();
+      c = get_symbol_name (&name);
       /* Argument sources.  */
       if ((strncasecmp (name, "argw", 4) == 0))
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = atoi (name + 4);
-         name = input_line_pointer;
-         c = get_symbol_end ();
+         c = get_symbol_name (&name);
          arg_reloc = pa_align_arg_reloc (temp, pa_build_arg_reloc (name));
 #if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
          symbol_arg_reloc_info (symbolP) |= arg_reloc;
+#else
+         (void) arg_reloc;
 #endif
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
       /* The return value.  */
       else if ((strncasecmp (name, "rtnval", 6)) == 0)
        {
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
          input_line_pointer++;
-         name = input_line_pointer;
-         c = get_symbol_end ();
+         c = get_symbol_name (&name);
          arg_reloc = pa_build_arg_reloc (name);
 #if defined (OBJ_SOM) || defined (ELF_ARG_RELOC)
          symbol_arg_reloc_info (symbolP) |= arg_reloc;
+#else
+         (void) arg_reloc;
 #endif
-         *input_line_pointer = c;
+         (void) restore_line_pointer (c);
        }
       /* Privilege level.  */
       else if ((strncasecmp (name, "priv_lev", 8)) == 0)
        {
-         p = input_line_pointer;
-         *p = c;
+         char *priv;
+
+         (void) restore_line_pointer (c);
          input_line_pointer++;
          temp = atoi (input_line_pointer);
 #ifdef OBJ_SOM
          ((obj_symbol_type *) bfdsym)->tc_data.ap.hppa_priv_level = temp;
 #endif
-         c = get_symbol_end ();
-         *input_line_pointer = c;
+         c = get_symbol_name (&priv);
+         (void) restore_line_pointer (c);
        }
       else
        {
          as_bad (_("Undefined .EXPORT/.IMPORT argument (ignored): %s"), name);
-         p = input_line_pointer;
-         *p = c;
+         (void) restore_line_pointer (c);
        }
+
       if (!is_end_of_statement ())
        input_line_pointer++;
     }
@@ -6644,17 +6683,15 @@ pa_type_args (symbolS *symbolP, int is_export)
 static void
 pa_export (int unused ATTRIBUTE_UNUSED)
 {
-  char *name, c, *p;
+  char *name, c;
   symbolS *symbol;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   /* Make sure the given symbol exists.  */
   if ((symbol = symbol_find_or_make (name)) == NULL)
     {
       as_bad (_("Cannot define export symbol: %s\n"), name);
-      p = input_line_pointer;
-      *p = c;
+      restore_line_pointer (c);
       input_line_pointer++;
     }
   else
@@ -6666,8 +6703,7 @@ pa_export (int unused ATTRIBUTE_UNUSED)
         set BSF_GLOBAL when we get back.  */
       S_SET_EXTERNAL (symbol);
       symbol_get_bfdsym (symbol)->flags |= BSF_GLOBAL;
-      p = input_line_pointer;
-      *p = c;
+      (void) restore_line_pointer (c);
       if (!is_end_of_statement ())
        {
          input_line_pointer++;
@@ -6685,11 +6721,10 @@ pa_export (int unused ATTRIBUTE_UNUSED)
 static void
 pa_import (int unused ATTRIBUTE_UNUSED)
 {
-  char *name, c, *p;
+  char *name, c;
   symbolS *symbol;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
   symbol = symbol_find (name);
   /* Ugh.  We might be importing a symbol defined earlier in the file,
@@ -6698,8 +6733,7 @@ pa_import (int unused ATTRIBUTE_UNUSED)
   if (symbol == NULL || !S_IS_DEFINED (symbol))
     {
       symbol = symbol_find_or_make (name);
-      p = input_line_pointer;
-      *p = c;
+      (void) restore_line_pointer (c);
 
       if (!is_end_of_statement ())
        {
@@ -6736,16 +6770,14 @@ pa_import (int unused ATTRIBUTE_UNUSED)
 static void
 pa_label (int unused ATTRIBUTE_UNUSED)
 {
-  char *name, c, *p;
+  char *name, c;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
   if (strlen (name) > 0)
     {
       colon (name);
-      p = input_line_pointer;
-      *p = c;
+      (void) restore_line_pointer (c);
     }
   else
     {
@@ -6834,24 +6866,21 @@ pa_origin (int unused ATTRIBUTE_UNUSED)
 static void
 pa_param (int unused ATTRIBUTE_UNUSED)
 {
-  char *name, c, *p;
+  char *name, c;
   symbolS *symbol;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
 
   if ((symbol = symbol_find_or_make (name)) == NULL)
     {
       as_bad (_("Cannot define static symbol: %s\n"), name);
-      p = input_line_pointer;
-      *p = c;
+      (void) restore_line_pointer (c);
       input_line_pointer++;
     }
   else
     {
       S_CLEAR_EXTERNAL (symbol);
-      p = input_line_pointer;
-      *p = c;
+      (void) restore_line_pointer (c);
       if (!is_end_of_statement ())
        {
          input_line_pointer++;
@@ -6883,7 +6912,7 @@ pa_proc (int unused ATTRIBUTE_UNUSED)
   within_procedure = TRUE;
 
   /* Create another call_info structure.  */
-  call_info = xmalloc (sizeof (struct call_info));
+  call_info = XNEW (struct call_info);
 
   if (!call_info)
     as_fatal (_("Cannot allocate unwind descriptor\n"));
@@ -6994,7 +7023,7 @@ pa_procend (int unused ATTRIBUTE_UNUSED)
 
 #ifdef OBJ_ELF
   /* ELF needs to mark the end of each function so that it can compute
-     the size of the function (apparently its needed in the symbol table).  */
+     the size of the function (apparently it's needed in the symbol table).  */
   hppa_elf_mark_end_of_function ();
 #endif
 
@@ -7038,7 +7067,7 @@ pa_check_current_space_and_subspace (void)
    by the parameters to the .SPACE directive.  */
 
 static sd_chain_struct *
-pa_parse_space_stmt (char *space_name, int create_flag)
+pa_parse_space_stmt (const char *space_name, int create_flag)
 {
   char *name, *ptemp, c;
   char loadable, defined, private, sort;
@@ -7088,39 +7117,38 @@ pa_parse_space_stmt (char *space_name, int create_flag)
          while (!is_end_of_statement ())
            {
              input_line_pointer++;
-             name = input_line_pointer;
-             c = get_symbol_end ();
+             c = get_symbol_name (&name);
              if ((strncasecmp (name, "spnum", 5) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
                  spnum = get_absolute_expression ();
                }
              else if ((strncasecmp (name, "sort", 4) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
                  sort = get_absolute_expression ();
                }
              else if ((strncasecmp (name, "unloadable", 10) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  loadable = FALSE;
                }
              else if ((strncasecmp (name, "notdefined", 10) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  defined = FALSE;
                }
              else if ((strncasecmp (name, "private", 7) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  private = TRUE;
                }
              else
                {
                  as_bad (_("Invalid .SPACE argument"));
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  if (!is_end_of_statement ())
                    input_line_pointer++;
                }
@@ -7258,11 +7286,9 @@ pa_space (int unused ATTRIBUTE_UNUSED)
       /* Not a number, attempt to create a new space.  */
       print_errors = 1;
       input_line_pointer = save_s;
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      space_name = xmalloc (strlen (name) + 1);
-      strcpy (space_name, name);
-      *input_line_pointer = c;
+      c = get_symbol_name (&name);
+      space_name = xstrdup (name);
+      (void) restore_line_pointer (c);
 
       sd_chain = pa_parse_space_stmt (space_name, 1);
       current_space = sd_chain;
@@ -7284,8 +7310,7 @@ pa_spnum (int unused ATTRIBUTE_UNUSED)
   char *p;
   sd_chain_struct *space;
 
-  name = input_line_pointer;
-  c = get_symbol_end ();
+  c = get_symbol_name (&name);
   space = is_defined_space (name);
   if (space)
     {
@@ -7295,7 +7320,7 @@ pa_spnum (int unused ATTRIBUTE_UNUSED)
   else
     as_warn (_("Undefined space: '%s' Assuming space number = 0."), name);
 
-  *input_line_pointer = c;
+  (void) restore_line_pointer (c);
   demand_empty_rest_of_line ();
 }
 
@@ -7310,7 +7335,7 @@ pa_subspace (int create_new)
 {
   char *name, *ss_name, c;
   char loadable, code_only, comdat, common, dup_common, zero, sort;
-  int i, access, space_index, alignment, quadrant, applicable, flags;
+  int i, access_ctr, space_index, alignment, quadrant, applicable, flags;
   sd_chain_struct *space;
   ssd_chain_struct *ssd;
   asection *section;
@@ -7325,15 +7350,13 @@ pa_subspace (int create_new)
     }
   else
     {
-      name = input_line_pointer;
-      c = get_symbol_end ();
-      ss_name = xmalloc (strlen (name) + 1);
-      strcpy (ss_name, name);
-      *input_line_pointer = c;
+      c = get_symbol_name (&name);
+      ss_name = xstrdup (name);
+      (void) restore_line_pointer (c);
 
       /* Load default values.  */
       sort = 0;
-      access = 0x7f;
+      access_ctr = 0x7f;
       loadable = 1;
       comdat = 0;
       common = 0;
@@ -7378,7 +7401,7 @@ pa_subspace (int create_new)
                  space_index = pa_def_subspaces[i].space_index;
                  alignment = pa_def_subspaces[i].alignment;
                  quadrant = pa_def_subspaces[i].quadrant;
-                 access = pa_def_subspaces[i].access;
+                 access_ctr = pa_def_subspaces[i].access;
                  sort = pa_def_subspaces[i].sort;
                  break;
                }
@@ -7393,17 +7416,16 @@ pa_subspace (int create_new)
          input_line_pointer++;
          while (!is_end_of_statement ())
            {
-             name = input_line_pointer;
-             c = get_symbol_end ();
+             c = get_symbol_name (&name);
              if ((strncasecmp (name, "quad", 4) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
                  quadrant = get_absolute_expression ();
                }
              else if ((strncasecmp (name, "align", 5) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
                  alignment = get_absolute_expression ();
                  if (exact_log2 (alignment) == -1)
@@ -7414,50 +7436,51 @@ pa_subspace (int create_new)
                }
              else if ((strncasecmp (name, "access", 6) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
-                 access = get_absolute_expression ();
+                 access_ctr = get_absolute_expression ();
                }
              else if ((strncasecmp (name, "sort", 4) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  input_line_pointer++;
                  sort = get_absolute_expression ();
                }
              else if ((strncasecmp (name, "code_only", 9) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  code_only = 1;
                }
              else if ((strncasecmp (name, "unloadable", 10) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  loadable = 0;
                }
              else if ((strncasecmp (name, "comdat", 6) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  comdat = 1;
                }
              else if ((strncasecmp (name, "common", 6) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  common = 1;
                }
              else if ((strncasecmp (name, "dup_comm", 8) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  dup_common = 1;
                }
              else if ((strncasecmp (name, "zero", 4) == 0))
                {
-                 *input_line_pointer = c;
+                 (void) restore_line_pointer (c);
                  zero = 1;
                }
              else if ((strncasecmp (name, "first", 5) == 0))
                as_bad (_("FIRST not supported as a .SUBSPACE argument"));
              else
                as_bad (_("Invalid .SUBSPACE argument"));
+
              if (!is_end_of_statement ())
                input_line_pointer++;
            }
@@ -7509,14 +7532,13 @@ pa_subspace (int create_new)
        seg_info (section)->bss = 1;
 
       /* Now set the flags.  */
-      bfd_set_section_flags (stdoutput, section, applicable);
+      bfd_set_section_flags (section, applicable);
 
       /* Record any alignment request for this section.  */
       record_alignment (section, exact_log2 (alignment));
 
       /* Set the starting offset for this section.  */
-      bfd_set_section_vma (stdoutput, section,
-                          pa_subspace_start (space, quadrant));
+      bfd_set_section_vma (section, pa_subspace_start (space, quadrant));
 
       /* Now that all the flags are set, update an existing subspace,
         or create a new one.  */
@@ -7524,14 +7546,14 @@ pa_subspace (int create_new)
 
        current_subspace = update_subspace (space, ss_name, loadable,
                                            code_only, comdat, common,
-                                           dup_common, sort, zero, access,
+                                           dup_common, sort, zero, access_ctr,
                                            space_index, alignment, quadrant,
                                            section);
       else
        current_subspace = create_new_subspace (space, ss_name, loadable,
                                                code_only, comdat, common,
                                                dup_common, zero, sort,
-                                               access, space_index,
+                                               access_ctr, space_index,
                                                alignment, quadrant, section);
 
       demand_empty_rest_of_line ();
@@ -7554,7 +7576,7 @@ pa_spaces_begin (void)
   i = 0;
   while (pa_def_spaces[i].name)
     {
-      char *name;
+      const char *name;
 
       /* Pick the right name to use for the new section.  */
       name = pa_def_spaces[i].name;
@@ -7570,7 +7592,7 @@ pa_spaces_begin (void)
   i = 0;
   while (pa_def_subspaces[i].name)
     {
-      char *name;
+      const char *name;
       int applicable, subsegment;
       asection *segment = NULL;
       sd_chain_struct *space;
@@ -7590,7 +7612,7 @@ pa_spaces_begin (void)
        {
          text_section = segment;
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & (SEC_ALLOC | SEC_LOAD
                                               | SEC_RELOC | SEC_CODE
                                               | SEC_READONLY
@@ -7600,7 +7622,7 @@ pa_spaces_begin (void)
        {
          data_section = segment;
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & (SEC_ALLOC | SEC_LOAD
                                               | SEC_RELOC
                                               | SEC_HAS_CONTENTS));
@@ -7610,13 +7632,13 @@ pa_spaces_begin (void)
        {
          bss_section = segment;
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & SEC_ALLOC);
        }
       else if (!strcmp (pa_def_subspaces[i].name, "$LIT$"))
        {
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & (SEC_ALLOC | SEC_LOAD
                                               | SEC_RELOC
                                               | SEC_READONLY
@@ -7625,7 +7647,7 @@ pa_spaces_begin (void)
       else if (!strcmp (pa_def_subspaces[i].name, "$MILLICODE$"))
        {
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & (SEC_ALLOC | SEC_LOAD
                                               | SEC_RELOC
                                               | SEC_READONLY
@@ -7634,7 +7656,7 @@ pa_spaces_begin (void)
       else if (!strcmp (pa_def_subspaces[i].name, "$UNWIND$"))
        {
          applicable = bfd_applicable_section_flags (stdoutput);
-         bfd_set_section_flags (stdoutput, segment,
+         bfd_set_section_flags (segment,
                                 applicable & (SEC_ALLOC | SEC_LOAD
                                               | SEC_RELOC
                                               | SEC_READONLY
@@ -7671,7 +7693,7 @@ pa_spaces_begin (void)
    by the given parameters.  */
 
 static sd_chain_struct *
-create_new_space (char *name,
+create_new_space (const char *name,
                  int spnum,
                  int loadable ATTRIBUTE_UNUSED,
                  int defined,
@@ -7682,13 +7704,8 @@ create_new_space (char *name,
 {
   sd_chain_struct *chain_entry;
 
-  chain_entry = xmalloc (sizeof (sd_chain_struct));
-  if (!chain_entry)
-    as_fatal (_("Out of memory: could not allocate new space chain entry: %s\n"),
-             name);
-
-  SPACE_NAME (chain_entry) = xmalloc (strlen (name) + 1);
-  strcpy (SPACE_NAME (chain_entry), name);
+  chain_entry = XNEW (sd_chain_struct);
+  SPACE_NAME (chain_entry) = xstrdup (name);
   SPACE_DEFINED (chain_entry) = defined;
   SPACE_USER_DEFINED (chain_entry) = user_defined;
   SPACE_SPNUM (chain_entry) = spnum;
@@ -7754,7 +7771,7 @@ create_new_space (char *name,
 
 static ssd_chain_struct *
 create_new_subspace (sd_chain_struct *space,
-                    char *name,
+                    const char *name,
                     int loadable ATTRIBUTE_UNUSED,
                     int code_only ATTRIBUTE_UNUSED,
                     int comdat,
@@ -7762,7 +7779,7 @@ create_new_subspace (sd_chain_struct *space,
                     int dup_common,
                     int is_zero ATTRIBUTE_UNUSED,
                     int sort,
-                    int access,
+                    int access_ctr,
                     int space_index ATTRIBUTE_UNUSED,
                     int alignment ATTRIBUTE_UNUSED,
                     int quadrant,
@@ -7770,12 +7787,8 @@ create_new_subspace (sd_chain_struct *space,
 {
   ssd_chain_struct *chain_entry;
 
-  chain_entry = xmalloc (sizeof (ssd_chain_struct));
-  if (!chain_entry)
-    as_fatal (_("Out of memory: could not allocate new subspace chain entry: %s\n"), name);
-
-  SUBSPACE_NAME (chain_entry) = xmalloc (strlen (name) + 1);
-  strcpy (SUBSPACE_NAME (chain_entry), name);
+  chain_entry = XNEW (ssd_chain_struct);
+  SUBSPACE_NAME (chain_entry) = xstrdup (name);
 
   /* Initialize subspace_defined.  When we hit a .subspace directive
      we'll set it to 1 which "locks-in" the subspace attributes.  */
@@ -7817,7 +7830,7 @@ create_new_subspace (sd_chain_struct *space,
     }
 
 #ifdef obj_set_subsection_attributes
-  obj_set_subsection_attributes (seg, space->sd_seg, access, sort,
+  obj_set_subsection_attributes (seg, space->sd_seg, access_ctr, sort,
                                 quadrant, comdat, common, dup_common);
 #endif
 
@@ -7837,7 +7850,7 @@ update_subspace (sd_chain_struct *space,
                 int dup_common,
                 int sort,
                 int zero ATTRIBUTE_UNUSED,
-                int access,
+                int access_ctr,
                 int space_index ATTRIBUTE_UNUSED,
                 int alignment ATTRIBUTE_UNUSED,
                 int quadrant,
@@ -7848,7 +7861,7 @@ update_subspace (sd_chain_struct *space,
   chain_entry = is_defined_subspace (name);
 
 #ifdef obj_set_subsection_attributes
-  obj_set_subsection_attributes (section, space->sd_seg, access, sort,
+  obj_set_subsection_attributes (section, space->sd_seg, access_ctr, sort,
                                 quadrant, comdat, common, dup_common);
 #endif
 
@@ -7859,7 +7872,7 @@ update_subspace (sd_chain_struct *space,
    NULL if no such space exists.  */
 
 static sd_chain_struct *
-is_defined_space (char *name)
+is_defined_space (const char *name)
 {
   sd_chain_struct *chain_pointer;
 
@@ -7908,7 +7921,7 @@ pa_segment_to_space (asection *seg)
    own subspace.  */
 
 static ssd_chain_struct *
-is_defined_subspace (char *name)
+is_defined_subspace (const char *name)
 {
   sd_chain_struct *space_chain;
   ssd_chain_struct *subspace_chain;
@@ -8434,7 +8447,7 @@ hppa_force_relocation (struct fix *fixp)
     return 1;
 #endif
 
-  assert (fixp->fx_addsy != NULL);
+  gas_assert (fixp->fx_addsy != NULL);
 
   /* Ensure we emit a relocation for global symbols so that dynamic
      linking works.  */
@@ -8514,11 +8527,11 @@ pa_vtable_entry (int ignore ATTRIBUTE_UNUSED)
 {
   struct fix *new_fix;
 
-  new_fix = obj_elf_vtable_entry (0);
+  new_fix = obj_elf_get_vtable_entry ();
 
   if (new_fix)
     {
-      struct hppa_fix_struct * hppa_fix = obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
+      struct hppa_fix_struct * hppa_fix = XOBNEW (&notes, struct hppa_fix_struct);
 
       hppa_fix->fx_r_type = R_HPPA;
       hppa_fix->fx_r_field = e_fsel;
@@ -8535,11 +8548,11 @@ pa_vtable_inherit (int ignore ATTRIBUTE_UNUSED)
 {
   struct fix *new_fix;
 
-  new_fix = obj_elf_vtable_inherit (0);
+  new_fix = obj_elf_get_vtable_inherit ();
 
   if (new_fix)
     {
-      struct hppa_fix_struct * hppa_fix = obstack_alloc (&notes, sizeof (struct hppa_fix_struct));
+      struct hppa_fix_struct * hppa_fix = XOBNEW (&notes, struct hppa_fix_struct);
 
       hppa_fix->fx_r_type = R_HPPA;
       hppa_fix->fx_r_field = e_fsel;
@@ -8656,7 +8669,7 @@ hppa_regname_to_dw2regnum (char *regname)
   unsigned int i;
   const char *p;
   char *q;
-  static struct { char *name; int dw2regnum; } regnames[] =
+  static struct { const char *name; int dw2regnum; } regnames[] =
     {
       { "sp", 30 }, { "rp", 2 },
     };
This page took 0.07111 seconds and 4 git commands to generate.