Home | History | Annotate | Download | only in gas
      1 /* messages.c - error reporter -
      2    Copyright (C) 1987-2016 Free Software Foundation, Inc.
      3    This file is part of GAS, the GNU Assembler.
      4 
      5    GAS is free software; you can redistribute it and/or modify
      6    it under the terms of the GNU General Public License as published by
      7    the Free Software Foundation; either version 3, or (at your option)
      8    any later version.
      9 
     10    GAS is distributed in the hope that it will be useful,
     11    but WITHOUT ANY WARRANTY; without even the implied warranty of
     12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     13    GNU General Public License for more details.
     14 
     15    You should have received a copy of the GNU General Public License
     16    along with GAS; see the file COPYING.  If not, write to the Free
     17    Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
     18    02110-1301, USA.  */
     19 
     20 #include "as.h"
     21 
     22 static void identify (const char *);
     23 static void as_show_where (void);
     24 static void as_warn_internal (const char *, unsigned int, char *);
     25 static void as_bad_internal (const char *, unsigned int, char *);
     26 
     27 /* Despite the rest of the comments in this file, (FIXME-SOON),
     28    here is the current scheme for error messages etc:
     29 
     30    as_fatal() is used when gas is quite confused and
     31    continuing the assembly is pointless.  In this case we
     32    exit immediately with error status.
     33 
     34    as_bad() is used to mark errors that result in what we
     35    presume to be a useless object file.  Say, we ignored
     36    something that might have been vital.  If we see any of
     37    these, assembly will continue to the end of the source,
     38    no object file will be produced, and we will terminate
     39    with error status.  The new option, -Z, tells us to
     40    produce an object file anyway but we still exit with
     41    error status.  The assumption here is that you don't want
     42    this object file but we could be wrong.
     43 
     44    as_warn() is used when we have an error from which we
     45    have a plausible error recovery.  eg, masking the top
     46    bits of a constant that is longer than will fit in the
     47    destination.  In this case we will continue to assemble
     48    the source, although we may have made a bad assumption,
     49    and we will produce an object file and return normal exit
     50    status (ie, no error).  The new option -X tells us to
     51    treat all as_warn() errors as as_bad() errors.  That is,
     52    no object file will be produced and we will exit with
     53    error status.  The idea here is that we don't kill an
     54    entire make because of an error that we knew how to
     55    correct.  On the other hand, sometimes you might want to
     56    stop the make at these points.
     57 
     58    as_tsktsk() is used when we see a minor error for which
     59    our error recovery action is almost certainly correct.
     60    In this case, we print a message and then assembly
     61    continues as though no error occurred.  */
     62 
     63 static void
     64 identify (const char *file)
     65 {
     66   static int identified;
     67 
     68   if (identified)
     69     return;
     70   identified++;
     71 
     72   if (!file)
     73     {
     74       unsigned int x;
     75       file = as_where (&x);
     76     }
     77 
     78   if (file)
     79     fprintf (stderr, "%s: ", file);
     80   fprintf (stderr, _("Assembler messages:\n"));
     81 }
     82 
     83 /* The number of warnings issued.  */
     84 static int warning_count;
     85 
     86 int
     87 had_warnings (void)
     88 {
     89   return warning_count;
     90 }
     91 
     92 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
     93    and exit with a nonzero error code.  */
     94 
     95 static int error_count;
     96 
     97 int
     98 had_errors (void)
     99 {
    100   return error_count;
    101 }
    102 
    103 /* Print the current location to stderr.  */
    104 
    105 static void
    106 as_show_where (void)
    107 {
    108   const char *file;
    109   unsigned int line;
    110 
    111   file = as_where (&line);
    112   identify (file);
    113   if (file)
    114     {
    115       if (line != 0)
    116 	fprintf (stderr, "%s:%u: ", file, line);
    117       else
    118 	fprintf (stderr, "%s: ", file);
    119     }
    120 }
    121 
    122 /* Send to stderr a string as a warning, and locate warning
    123    in input file(s).
    124    Please only use this for when we have some recovery action.
    125    Please explain in string (which may have '\n's) what recovery was
    126    done.  */
    127 
    128 void
    129 as_tsktsk (const char *format, ...)
    130 {
    131   va_list args;
    132 
    133   as_show_where ();
    134   va_start (args, format);
    135   vfprintf (stderr, format, args);
    136   va_end (args);
    137   (void) putc ('\n', stderr);
    138 }
    139 
    140 /* The common portion of as_warn and as_warn_where.  */
    141 
    142 static void
    143 as_warn_internal (const char *file, unsigned int line, char *buffer)
    144 {
    145   ++warning_count;
    146 
    147   if (file == NULL)
    148     file = as_where (&line);
    149 
    150   identify (file);
    151   if (file)
    152     {
    153       if (line != 0)
    154 	fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer);
    155       else
    156 	fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer);
    157     }
    158   else
    159     fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
    160 #ifndef NO_LISTING
    161   listing_warning (buffer);
    162 #endif
    163 }
    164 
    165 /* Send to stderr a string as a warning, and locate warning
    166    in input file(s).
    167    Please only use this for when we have some recovery action.
    168    Please explain in string (which may have '\n's) what recovery was
    169    done.  */
    170 
    171 void
    172 as_warn (const char *format, ...)
    173 {
    174   va_list args;
    175   char buffer[2000];
    176 
    177   if (!flag_no_warnings)
    178     {
    179       va_start (args, format);
    180       vsnprintf (buffer, sizeof (buffer), format, args);
    181       va_end (args);
    182       as_warn_internal ((char *) NULL, 0, buffer);
    183     }
    184 }
    185 
    186 /* Like as_bad but the file name and line number are passed in.
    187    Unfortunately, we have to repeat the function in order to handle
    188    the varargs correctly and portably.  */
    189 
    190 void
    191 as_warn_where (const char *file, unsigned int line, const char *format, ...)
    192 {
    193   va_list args;
    194   char buffer[2000];
    195 
    196   if (!flag_no_warnings)
    197     {
    198       va_start (args, format);
    199       vsnprintf (buffer, sizeof (buffer), format, args);
    200       va_end (args);
    201       as_warn_internal (file, line, buffer);
    202     }
    203 }
    204 
    205 /* The common portion of as_bad and as_bad_where.  */
    206 
    207 static void
    208 as_bad_internal (const char *file, unsigned int line, char *buffer)
    209 {
    210   ++error_count;
    211 
    212   if (file == NULL)
    213     file = as_where (&line);
    214 
    215   identify (file);
    216   if (file)
    217     {
    218       if (line != 0)
    219 	fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer);
    220       else
    221 	fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer);
    222     }
    223   else
    224     fprintf (stderr, "%s%s\n", _("Error: "), buffer);
    225 #ifndef NO_LISTING
    226   listing_error (buffer);
    227 #endif
    228 }
    229 
    230 /* Send to stderr a string as a warning, and locate warning in input
    231    file(s).  Please use when there is no recovery, but we want to
    232    continue processing but not produce an object file.
    233    Please explain in string (which may have '\n's) what recovery was
    234    done.  */
    235 
    236 void
    237 as_bad (const char *format, ...)
    238 {
    239   va_list args;
    240   char buffer[2000];
    241 
    242   va_start (args, format);
    243   vsnprintf (buffer, sizeof (buffer), format, args);
    244   va_end (args);
    245 
    246   as_bad_internal ((char *) NULL, 0, buffer);
    247 }
    248 
    249 /* Like as_bad but the file name and line number are passed in.
    250    Unfortunately, we have to repeat the function in order to handle
    251    the varargs correctly and portably.  */
    252 
    253 void
    254 as_bad_where (const char *file, unsigned int line, const char *format, ...)
    255 {
    256   va_list args;
    257   char buffer[2000];
    258 
    259   va_start (args, format);
    260   vsnprintf (buffer, sizeof (buffer), format, args);
    261   va_end (args);
    262 
    263   as_bad_internal (file, line, buffer);
    264 }
    265 
    266 /* Send to stderr a string as a fatal message, and print location of
    267    error in input file(s).
    268    Please only use this for when we DON'T have some recovery action.
    269    It xexit()s with a warning status.  */
    270 
    271 void
    272 as_fatal (const char *format, ...)
    273 {
    274   va_list args;
    275 
    276   as_show_where ();
    277   va_start (args, format);
    278   fprintf (stderr, _("Fatal error: "));
    279   vfprintf (stderr, format, args);
    280   (void) putc ('\n', stderr);
    281   va_end (args);
    282   /* Delete the output file, if it exists.  This will prevent make from
    283      thinking that a file was created and hence does not need rebuilding.  */
    284   if (out_file_name != NULL)
    285     unlink_if_ordinary (out_file_name);
    286   xexit (EXIT_FAILURE);
    287 }
    288 
    289 /* Indicate assertion failure.
    290    Arguments: Filename, line number, optional function name.  */
    291 
    292 void
    293 as_assert (const char *file, int line, const char *fn)
    294 {
    295   as_show_where ();
    296   fprintf (stderr, _("Internal error!\n"));
    297   if (fn)
    298     fprintf (stderr, _("Assertion failure in %s at %s:%d.\n"),
    299 	     fn, file, line);
    300   else
    301     fprintf (stderr, _("Assertion failure at %s:%d.\n"), file, line);
    302   fprintf (stderr, _("Please report this bug.\n"));
    303   xexit (EXIT_FAILURE);
    304 }
    305 
    306 /* as_abort: Print a friendly message saying how totally hosed we are,
    307    and exit without producing a core file.  */
    308 
    309 void
    310 as_abort (const char *file, int line, const char *fn)
    311 {
    312   as_show_where ();
    313   if (fn)
    314     fprintf (stderr, _("Internal error, aborting at %s:%d in %s\n"),
    315 	     file, line, fn);
    316   else
    317     fprintf (stderr, _("Internal error, aborting at %s:%d\n"),
    318 	     file, line);
    319   fprintf (stderr, _("Please report this bug.\n"));
    320   xexit (EXIT_FAILURE);
    321 }
    322 
    323 /* Support routines.  */
    324 
    325 void
    326 sprint_value (char *buf, valueT val)
    327 {
    328   if (sizeof (val) <= sizeof (long))
    329     {
    330       sprintf (buf, "%ld", (long) val);
    331       return;
    332     }
    333   if (sizeof (val) <= sizeof (bfd_vma))
    334     {
    335       sprintf_vma (buf, val);
    336       return;
    337     }
    338   abort ();
    339 }
    340 
    341 #define HEX_MAX_THRESHOLD	1024
    342 #define HEX_MIN_THRESHOLD	-(HEX_MAX_THRESHOLD)
    343 
    344 static void
    345 as_internal_value_out_of_range (const char *prefix,
    346 				offsetT val,
    347 				offsetT min,
    348 				offsetT max,
    349 				const char *file,
    350 				unsigned line,
    351 				int bad)
    352 {
    353   const char * err;
    354 
    355   if (prefix == NULL)
    356     prefix = "";
    357 
    358   if (val >= min && val <= max)
    359     {
    360       addressT right = max & -max;
    361 
    362       if (max <= 1)
    363 	abort ();
    364 
    365       /* xgettext:c-format  */
    366       err = _("%s out of domain (%d is not a multiple of %d)");
    367       if (bad)
    368 	as_bad_where (file, line, err,
    369 		      prefix, (int) val, (int) right);
    370       else
    371 	as_warn_where (file, line, err,
    372 		       prefix, (int) val, (int) right);
    373       return;
    374     }
    375 
    376   if (   val < HEX_MAX_THRESHOLD
    377       && min < HEX_MAX_THRESHOLD
    378       && max < HEX_MAX_THRESHOLD
    379       && val > HEX_MIN_THRESHOLD
    380       && min > HEX_MIN_THRESHOLD
    381       && max > HEX_MIN_THRESHOLD)
    382     {
    383       /* xgettext:c-format  */
    384       err = _("%s out of range (%d is not between %d and %d)");
    385 
    386       if (bad)
    387 	as_bad_where (file, line, err,
    388 		      prefix, (int) val, (int) min, (int) max);
    389       else
    390 	as_warn_where (file, line, err,
    391 		       prefix, (int) val, (int) min, (int) max);
    392     }
    393   else
    394     {
    395       char val_buf [sizeof (val) * 3 + 2];
    396       char min_buf [sizeof (val) * 3 + 2];
    397       char max_buf [sizeof (val) * 3 + 2];
    398 
    399       if (sizeof (val) > sizeof (bfd_vma))
    400 	abort ();
    401 
    402       sprintf_vma (val_buf, (bfd_vma) val);
    403       sprintf_vma (min_buf, (bfd_vma) min);
    404       sprintf_vma (max_buf, (bfd_vma) max);
    405 
    406       /* xgettext:c-format.  */
    407       err = _("%s out of range (0x%s is not between 0x%s and 0x%s)");
    408 
    409       if (bad)
    410 	as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf);
    411       else
    412 	as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf);
    413     }
    414 }
    415 
    416 void
    417 as_warn_value_out_of_range (const char *prefix,
    418 			   offsetT value,
    419 			   offsetT min,
    420 			   offsetT max,
    421 			   const char *file,
    422 			   unsigned line)
    423 {
    424   as_internal_value_out_of_range (prefix, value, min, max, file, line, 0);
    425 }
    426 
    427 void
    428 as_bad_value_out_of_range (const char *prefix,
    429 			   offsetT value,
    430 			   offsetT min,
    431 			   offsetT max,
    432 			   const char *file,
    433 			   unsigned line)
    434 {
    435   as_internal_value_out_of_range (prefix, value, min, max, file, line, 1);
    436 }
    437