print_errors = 1;
       input_line_pointer = save_s;
       c = get_symbol_name (&name);
-      space_name = xmalloc (strlen (name) + 1);
-      strcpy (space_name, name);
+      space_name = xstrdup (name);
       (void) restore_line_pointer (c);
 
       sd_chain = pa_parse_space_stmt (space_name, 1);
   else
     {
       c = get_symbol_name (&name);
-      ss_name = xmalloc (strlen (name) + 1);
-      strcpy (ss_name, name);
+      ss_name = xstrdup (name);
       (void) restore_line_pointer (c);
 
       /* Load default values.  */
     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);
+  SPACE_NAME (chain_entry) = xstrdup (name);
   SPACE_DEFINED (chain_entry) = defined;
   SPACE_USER_DEFINED (chain_entry) = user_defined;
   SPACE_SPNUM (chain_entry) = spnum;
   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);
+  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.  */
 
   struct mips_opcode *insn;
 
   /* Make a copy of the instruction so that we can fiddle with it.  */
-  name = xmalloc (length + 1);
-  memcpy (name, start, length);
-  name[length] = '\0';
+  name = xstrndup (start, length);
 
   /* Look up the instruction as-is.  */
   insn = (struct mips_opcode *) hash_find (hash, name);
 
   char c;
   char *name;
   char *str;
-  char *tmp;
 
   SKIP_WHITESPACE ();
   str = input_line_pointer;
     }
   *input_line_pointer++ = '\0';
   c = get_symbol_name (&name); /* Get terminator.  */
-  tmp = xmalloc (strlen (str) + 1);
-  strcpy (tmp, str);
-  str = tmp;
-  tmp = xmalloc (strlen (name) + 1);
-  strcpy (tmp, name);
-  name = tmp;
+  str = xstrdup (str);
+  name = xstrdup (name);
   if (hash_find (tic4x_asg_hash, name))
     hash_replace (tic4x_asg_hash, name, (void *) str);
   else
 
       return;
     }
   c = get_symbol_name (&name); /* Get terminator.  */
-  tmp = xmalloc (strlen (name) + 1);
-  name = strcpy (tmp, name);
+  name = xstrdup (name);
   (void) restore_line_pointer (c);
 
   if (!ISALPHA (*name))
      But since there's not written rule as to when, don't even bother trying
      to match their behavior.  */
   sprintf (valuestr, "%d", value);
-  tmp = xmalloc (strlen (valuestr) + 1);
-  strcpy (tmp, valuestr);
+  tmp = xstrdup (valuestr);
   subsym_create_or_replace (name, tmp);
 
   demand_empty_rest_of_line ();
   struct stag_field *sfield = xmalloc (sizeof (struct stag_field));
 
   memset (sfield, 0, sizeof (*sfield));
-  sfield->name = strcpy (xmalloc (strlen (name) + 1), name);
+  sfield->name = xstrdup (name);
   sfield->offset = offset;
   sfield->bitfield_offset = parent->current_bitfield_offset;
   sfield->stag = stag;
   current_subseg = now_subseg; /* Save current subseg.  */
 
   c = get_symbol_name (§ion_name); /* Get terminator.  */
-  name = xmalloc (input_line_pointer - section_name + 1);
-  strcpy (name, section_name);
+  name = xstrdup (section_name);
   c = restore_line_pointer (c);
   
   if (c == ',')
        ;
       know (input_line_pointer[-1] == '\"');
       input_line_pointer[-1] = 0;
-      name = xmalloc (input_line_pointer - section_name + 1);
-      strcpy (name, section_name);
+      name = xstrdup (section_name);
 
       seg = bfd_get_section_by_name (stdoutput, name);
       if (seg == NULL)
       unsigned lineno;
 
       curfile = as_where (&lineno);
-      dir = strcpy (xmalloc (strlen (curfile) + 1), curfile);
+      dir = xstrdup (curfile);
       tmp = strrchr (dir, '/');
     }
   if (tmp != NULL)
        ++input_line_pointer;
       c = *input_line_pointer;
       *input_line_pointer = '\0';
-      filename = strcpy (xmalloc (strlen (filename) + 1), filename);
+      filename = xstrdup (filename);
       *input_line_pointer = c;
       demand_empty_rest_of_line ();
     }
        ++input_line_pointer;
       c = *input_line_pointer;
       *input_line_pointer = 0;
-      msg = strcpy (xmalloc (strlen (msg) + 1), msg);
+      msg = xstrdup (msg);
       *input_line_pointer = c;
     }
 
          char *section_name;
 
          c = get_symbol_name (§ion_name);
-         name = xmalloc (strlen (section_name) + 1);
-         strcpy (name, section_name);
+         name = xstrdup (section_name);
          (void) restore_line_pointer (c);
        }
 
        }
       c = get_symbol_name (&name);
       /* .var symbols start out with a null string.  */
-      name = strcpy (xmalloc (strlen (name) + 1), name);
+      name = xstrdup (name);
       hash_insert (subsym_hash[macro_level], name, empty);
       c = restore_line_pointer (c);
       if (c == ',')
       return 0;
     }
 
-  ptr = elem = xmalloc (strlen (listv) + 1);
-  strcpy (elem, listv);
+  ptr = elem = xstrdup (listv);
   while (*ptr && *ptr != ',')
     ++ptr;
   *ptr++ = 0;
   char *tmp;
 
   /* Work with a copy of the input line.  */
-  replacement = xmalloc (strlen (line) + 1);
-  strcpy (replacement, line);
+  replacement = xstrdup (line);
 
   ptr = head = replacement;
 
                         kinda indicates that forced substitution is not
                         supposed to be recursive, but I'm not sure.  */
                      unsigned beg, len = 1; /* default to a single char */
-                     char *newval = strcpy (xmalloc (strlen (value) + 1),
-                                            value);
+                     char *newval = xstrdup (value);
 
                      savedp = input_line_pointer;
                      input_line_pointer = tail + 1;
 
 xg_replace_opname (char **popname, const char *newop)
 {
   free (*popname);
-  *popname = (char *) xmalloc (strlen (newop) + 1);
-  strcpy (*popname, newop);
+  *popname = xstrdup (newop);
 }
 
 
   /* Another special case for "WSR.INTSET"....  */
   if (is_write && !is_user && !strcasecmp ("interrupt", sr_name))
     sr_name = "intset";
-  new_opname = (char *) xmalloc (strlen (sr_name) + 6);
-  sprintf (new_opname, "%s.%s", *popname, sr_name);
+  new_opname = concat (*popname, ".", sr_name, (char *) NULL);
   free (*popname);
   *popname = new_opname;
 
          if (xg_check_num_args (pnum_args, 2, opname, arg_strings))
            return -1;
          xg_replace_opname (popname, (has_underbar ? "_or" : "or"));
-         arg_strings[2] = (char *) xmalloc (strlen (arg_strings[1]) + 1);
-         strcpy (arg_strings[2], arg_strings[1]);
+         arg_strings[2] = xstrdup (arg_strings[1]);
          *pnum_args = 3;
        }
       return 0;
          if (xg_check_num_args (pnum_args, 0, opname, arg_strings))
            return -1;
          xg_replace_opname (popname, (has_underbar ? "_or" : "or"));
-         arg_strings[0] = (char *) xmalloc (3);
-         arg_strings[1] = (char *) xmalloc (3);
-         arg_strings[2] = (char *) xmalloc (3);
-         strcpy (arg_strings[0], "a1");
-         strcpy (arg_strings[1], "a1");
-         strcpy (arg_strings[2], "a1");
+         arg_strings[0] = xstrdup ("a1");
+         arg_strings[1] = xstrdup ("a1");
+         arg_strings[2] = xstrdup ("a1");
          *pnum_args = 3;
        }
       return 0;
 
   /* Split off the opcode.  */
   opnamelen = strspn (str, "abcdefghijklmnopqrstuvwxyz_/0123456789.");
-  opname = xmalloc (opnamelen + 1);
-  memcpy (opname, str, opnamelen);
-  opname[opnamelen] = '\0';
+  opname = xstrndup (str, opnamelen);
 
   num_args = tokenize_arguments (arg_strings, str + opnamelen);
   if (num_args == -1)
   base_name = use_abs_literals ? ".lit4" : ".literal";
   if (group_name)
     {
-      name = xmalloc (strlen (base_name) + strlen (group_name) + 2);
-      sprintf (name, "%s.%s", base_name, group_name);
+      name = concat (base_name, ".", group_name, (char *) NULL);
     }
   else if (strncmp (text_name, ".gnu.linkonce.", linkonce_len) == 0)
     {
       suffix = strchr (text_name + linkonce_len, '.');
 
-      name = xmalloc (linkonce_len + strlen (base_name) + 1
-                     + (suffix ? strlen (suffix) : 0));
-      strcpy (name, ".gnu.linkonce");
-      strcat (name, base_name);
-      if (suffix)
-       strcat (name, suffix);
+      name = concat (".gnu.linkonce", base_name, suffix ? suffix : "",
+                    (char *) NULL);
       linkonce = TRUE;
     }
   else