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