Guard against 'current_directory == NULL' on gdb_abspath (PR gdb/23613)
[deliverable/binutils-gdb.git] / gas / config / tc-nios2.c
index a62e3cbf784857ad09ea902b7753077144a870c8..f1a02001f8c59054621ac835ac23c4f0c3612511 100644 (file)
@@ -1,5 +1,5 @@
 /* Altera Nios II assembler.
-   Copyright (C) 2012-2016 Free Software Foundation, Inc.
+   Copyright (C) 2012-2019 Free Software Foundation, Inc.
    Contributed by Nigel Gray (ngray@altera.com).
    Contributed by Mentor Graphics, Inc.
 
@@ -25,7 +25,6 @@
 #include "elf/nios2.h"
 #include "tc-nios2.h"
 #include "bfd.h"
-#include "libbfd.h"
 #include "dwarf2dbg.h"
 #include "subsegs.h"
 #include "safe-ctype.h"
@@ -207,7 +206,7 @@ static segT nios2_current_align_seg;
 static int nios2_auto_align_on = 1;
 
 /* The last seen label in the current section.  This is used to auto-align
-   labels preceeding instructions.  */
+   labels preceding instructions.  */
 static symbolS *nios2_last_label;
 
 /* If we saw a 16-bit CDX instruction, we can align on 2-byte boundaries
@@ -728,8 +727,8 @@ const pseudo_typeS md_pseudo_table[] = {
 #define CDX_CBRANCH_SUBTYPE(N) (CDXBRANCH | CBRANCH | (N))
 #define SUBTYPE_ADDIS(SUBTYPE) ((SUBTYPE) & 0xffff)
 
-/* For the -relax-section mode, unconditional branches require 2 extra i
-   nstructions besides the addis, conditional branches require 3.  */
+/* For the -relax-section mode, unconditional branches require 2 extra
+   instructions besides the addis, conditional branches require 3.  */
 #define UBRANCH_ADDIS_TO_SIZE(N) (((N) + 2) * 4)
 #define CBRANCH_ADDIS_TO_SIZE(N) (((N) + 3) * 4)
 
@@ -1128,7 +1127,7 @@ nios2_check_overflow (valueT fixup, reloc_howto_type *howto)
       if ((fixup & 0x80000000) > 0)
        {
          /* Check for negative overflow.  */
-         if ((signed) fixup < ((signed) ~0 << (howto->bitsize-1)))
+         if ((signed) fixup < (signed) (~0U << (howto->bitsize - 1)))
            return TRUE;
        }
       else
@@ -1385,7 +1384,7 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
            nios2_diagnose_overflow (fixup, howto, fixP, value);
 
          /* Apply the right shift.  */
-         fixup = ((signed)fixup) >> howto->rightshift;
+         fixup = (offsetT) fixup >> howto->rightshift;
 
          /* Truncate the fixup to right size.  */
          switch (fixP->fx_r_type)
@@ -1397,13 +1396,11 @@ md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
              fixup = fixup & 0xFFFF;
              break;
            case BFD_RELOC_NIOS2_HIADJ16:
-             fixup = ((((fixup >> 16) & 0xFFFF) + ((fixup >> 15) & 0x01))
-                      & 0xFFFF);
+             fixup = ((fixup + 0x8000) >> 16) & 0xFFFF;
              break;
            default:
              {
-               int n = sizeof (fixup) * 8 - howto->bitsize;
-               fixup = (fixup << n) >> n;
+               fixup &= ((valueT) 1 << howto->bitsize) - 1;
                break;
              }
            }
@@ -1482,7 +1479,7 @@ static nios2_insn_relocS *
 nios2_insn_reloc_new (bfd_reloc_code_real_type reloc_type, unsigned int pcrel)
 {
   nios2_insn_relocS *retval;
-  retval = (nios2_insn_relocS *) malloc (sizeof (nios2_insn_relocS));
+  retval = XNEW (nios2_insn_relocS);
   if (retval == NULL)
     {
       as_bad (_("can't create relocation"));
@@ -3245,16 +3242,29 @@ static nios2_ps_insn_infoS*
 nios2_translate_pseudo_insn (nios2_insn_infoS *insn)
 {
 
+  const struct nios2_opcode *op = insn->insn_nios2_opcode;
   nios2_ps_insn_infoS *ps_insn;
+  unsigned int tokidx, ntok;
 
-  /* Find which real insn the pseudo-op transates to and
+  /* Find which real insn the pseudo-op translates to and
      switch the insn_info ptr to point to it.  */
-  ps_insn = nios2_ps_lookup (insn->insn_nios2_opcode->name);
+  ps_insn = nios2_ps_lookup (op->name);
 
   if (ps_insn != NULL)
     {
       insn->insn_nios2_opcode = nios2_opcode_lookup (ps_insn->insn);
       insn->insn_tokens[0] = insn->insn_nios2_opcode->name;
+      
+      /* Make sure there are enough arguments.  */
+      ntok = ((op->pinfo & NIOS2_INSN_OPTARG)
+             ? op->num_args - 1 : op->num_args);
+      for (tokidx = 1; tokidx <= ntok; tokidx++)
+       if (insn->insn_tokens[tokidx] == NULL)
+         {
+           as_bad ("missing argument");
+           return NULL;
+         }
+
       /* Modify the args so they work with the real insn.  */
       ps_insn->arg_modifer_func ((char **) insn->insn_tokens,
                                 ps_insn->arg_modifier, ps_insn->num,
@@ -3685,6 +3695,7 @@ md_assemble (char *op_str)
   unsigned long saved_pinfo = 0;
   nios2_insn_infoS thisinsn;
   nios2_insn_infoS *insn = &thisinsn;
+  bfd_boolean ps_error = FALSE;
 
   /* Make sure we are aligned on an appropriate boundary.  */
   if (nios2_current_align < nios2_min_align)
@@ -3731,35 +3742,45 @@ md_assemble (char *op_str)
         with its real equivalent, and then continue.  */
       if ((insn->insn_nios2_opcode->pinfo & NIOS2_INSN_MACRO)
          == NIOS2_INSN_MACRO)
-       ps_insn = nios2_translate_pseudo_insn (insn);
-
-      /* Assemble the parsed arguments into the instruction word.  */
-      nios2_assemble_args (insn);
-
-      /* Handle relaxation and other transformations.  */
-      if (nios2_as_options.relax != relax_none
-         && !nios2_as_options.noat
-         && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH)
-       output_ubranch (insn);
-      else if (nios2_as_options.relax != relax_none
-              && !nios2_as_options.noat
-              && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH)
-       output_cbranch (insn);
-      else if (nios2_as_options.relax == relax_all
-              && !nios2_as_options.noat
-              && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
-              && insn->insn_reloc
-              && ((insn->insn_reloc->reloc_type
-                   == BFD_RELOC_NIOS2_CALL26)
-                  || (insn->insn_reloc->reloc_type
-                      == BFD_RELOC_NIOS2_CALL26_NOAT)))
-       output_call (insn);
-      else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA)
-       output_movia (insn);
-      else
-       output_insn (insn);
-      if (ps_insn)
-       nios2_cleanup_pseudo_insn (insn, ps_insn);
+       {
+         ps_insn = nios2_translate_pseudo_insn (insn);
+         if (!ps_insn)
+           ps_error = TRUE;
+       }
+
+      /* If we found invalid pseudo-instruction syntax, the error's already
+        been diagnosed in nios2_translate_pseudo_insn, so skip
+        remaining processing.  */
+      if (!ps_error)
+       {
+         /* Assemble the parsed arguments into the instruction word.  */
+         nios2_assemble_args (insn);
+
+         /* Handle relaxation and other transformations.  */
+         if (nios2_as_options.relax != relax_none
+             && !nios2_as_options.noat
+             && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_UBRANCH)
+           output_ubranch (insn);
+         else if (nios2_as_options.relax != relax_none
+                  && !nios2_as_options.noat
+                  && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CBRANCH)
+           output_cbranch (insn);
+         else if (nios2_as_options.relax == relax_all
+                  && !nios2_as_options.noat
+                  && insn->insn_nios2_opcode->pinfo & NIOS2_INSN_CALL
+                  && insn->insn_reloc
+                  && ((insn->insn_reloc->reloc_type
+                       == BFD_RELOC_NIOS2_CALL26)
+                      || (insn->insn_reloc->reloc_type
+                          == BFD_RELOC_NIOS2_CALL26_NOAT)))
+           output_call (insn);
+         else if (saved_pinfo == NIOS2_INSN_MACRO_MOVIA)
+           output_movia (insn);
+         else
+           output_insn (insn);
+         if (ps_insn)
+           nios2_cleanup_pseudo_insn (insn, ps_insn);
+       }
     }
   else
     /* Unrecognised instruction - error.  */
@@ -3854,8 +3875,8 @@ nios2_frob_symbol (symbolS *symp)
 arelent *
 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
 {
-  arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
-  reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
+  arelent *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;
This page took 0.029772 seconds and 4 git commands to generate.