xref: /netbsd-src/external/gpl3/binutils.old/dist/gas/messages.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /* messages.c - error reporter -
2    Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001,
3    2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011
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 3, 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 
24 static void identify (char *);
25 static void as_show_where (void);
26 static void as_warn_internal (char *, unsigned int, char *);
27 static 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 
65 static void
66 identify (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.  */
86 static int warning_count;
87 
88 int
89 had_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 
97 static int error_count;
98 
99 int
100 had_errors (void)
101 {
102   return error_count;
103 }
104 
105 /* Print the current location to stderr.  */
106 
107 static void
108 as_show_where (void)
109 {
110   char *file;
111   unsigned int line;
112 
113   as_where (&file, &line);
114   identify (file);
115   if (file)
116     {
117       if (line != 0)
118 	fprintf (stderr, "%s:%u: ", file, line);
119       else
120 	fprintf (stderr, "%s: ", file);
121     }
122 }
123 
124 /* Send to stderr a string as a warning, and locate warning
125    in input file(s).
126    Please only use this for when we have some recovery action.
127    Please explain in string (which may have '\n's) what recovery was
128    done.  */
129 
130 void
131 as_tsktsk (const char *format, ...)
132 {
133   va_list args;
134 
135   as_show_where ();
136   va_start (args, format);
137   vfprintf (stderr, format, args);
138   va_end (args);
139   (void) putc ('\n', stderr);
140 }
141 
142 /* The common portion of as_warn and as_warn_where.  */
143 
144 static void
145 as_warn_internal (char *file, unsigned int line, char *buffer)
146 {
147   ++warning_count;
148 
149   if (file == NULL)
150     as_where (&file, &line);
151 
152   identify (file);
153   if (file)
154     {
155       if (line != 0)
156 	fprintf (stderr, "%s:%u: ", file, line);
157       else
158 	fprintf (stderr, "%s: ", file);
159     }
160   fprintf (stderr, _("Warning: "));
161   fputs (buffer, stderr);
162   (void) putc ('\n', stderr);
163 #ifndef NO_LISTING
164   listing_warning (buffer);
165 #endif
166 }
167 
168 /* Send to stderr a string as a warning, and locate warning
169    in input file(s).
170    Please only use this for when we have some recovery action.
171    Please explain in string (which may have '\n's) what recovery was
172    done.  */
173 
174 void
175 as_warn (const char *format, ...)
176 {
177   va_list args;
178   char buffer[2000];
179 
180   if (!flag_no_warnings)
181     {
182       va_start (args, format);
183       vsnprintf (buffer, sizeof (buffer), format, args);
184       va_end (args);
185       as_warn_internal ((char *) NULL, 0, buffer);
186     }
187 }
188 
189 /* Like as_bad but the file name and line number are passed in.
190    Unfortunately, we have to repeat the function in order to handle
191    the varargs correctly and portably.  */
192 
193 void
194 as_warn_where (char *file, unsigned int line, const char *format, ...)
195 {
196   va_list args;
197   char buffer[2000];
198 
199   if (!flag_no_warnings)
200     {
201       va_start (args, format);
202       vsnprintf (buffer, sizeof (buffer), format, args);
203       va_end (args);
204       as_warn_internal (file, line, buffer);
205     }
206 }
207 
208 /* The common portion of as_bad and as_bad_where.  */
209 
210 static void
211 as_bad_internal (char *file, unsigned int line, char *buffer)
212 {
213   ++error_count;
214 
215   if (file == NULL)
216     as_where (&file, &line);
217 
218   identify (file);
219   if (file)
220     {
221       if (line != 0)
222 	fprintf (stderr, "%s:%u: ", file, line);
223       else
224 	fprintf (stderr, "%s: ", file);
225     }
226   fprintf (stderr, _("Error: "));
227   fputs (buffer, stderr);
228   (void) putc ('\n', stderr);
229 #ifndef NO_LISTING
230   listing_error (buffer);
231 #endif
232 }
233 
234 /* Send to stderr a string as a warning, and locate warning in input
235    file(s).  Please us when there is no recovery, but we want to
236    continue processing but not produce an object file.
237    Please explain in string (which may have '\n's) what recovery was
238    done.  */
239 
240 void
241 as_bad (const char *format, ...)
242 {
243   va_list args;
244   char buffer[2000];
245 
246   va_start (args, format);
247   vsnprintf (buffer, sizeof (buffer), format, args);
248   va_end (args);
249 
250   as_bad_internal ((char *) NULL, 0, buffer);
251 }
252 
253 /* Like as_bad but the file name and line number are passed in.
254    Unfortunately, we have to repeat the function in order to handle
255    the varargs correctly and portably.  */
256 
257 void
258 as_bad_where (char *file, unsigned int line, const char *format, ...)
259 {
260   va_list args;
261   char buffer[2000];
262 
263   va_start (args, format);
264   vsnprintf (buffer, sizeof (buffer), format, args);
265   va_end (args);
266 
267   as_bad_internal (file, line, buffer);
268 }
269 
270 /* Send to stderr a string as a fatal message, and print location of
271    error in input file(s).
272    Please only use this for when we DON'T have some recovery action.
273    It xexit()s with a warning status.  */
274 
275 void
276 as_fatal (const char *format, ...)
277 {
278   va_list args;
279 
280   as_show_where ();
281   va_start (args, format);
282   fprintf (stderr, _("Fatal error: "));
283   vfprintf (stderr, format, args);
284   (void) putc ('\n', stderr);
285   va_end (args);
286   /* Delete the output file, if it exists.  This will prevent make from
287      thinking that a file was created and hence does not need rebuilding.  */
288   if (out_file_name != NULL)
289     unlink_if_ordinary (out_file_name);
290   xexit (EXIT_FAILURE);
291 }
292 
293 /* Indicate assertion failure.
294    Arguments: Filename, line number, optional function name.  */
295 
296 void
297 as_assert (const char *file, int line, const char *fn)
298 {
299   as_show_where ();
300   fprintf (stderr, _("Internal error!\n"));
301   if (fn)
302     fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
303 	     fn, file, line);
304   else
305     fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
306   fprintf (stderr, _("Please report this bug.\n"));
307   xexit (EXIT_FAILURE);
308 }
309 
310 /* as_abort: Print a friendly message saying how totally hosed we are,
311    and exit without producing a core file.  */
312 
313 void
314 as_abort (const char *file, int line, const char *fn)
315 {
316   as_show_where ();
317   if (fn)
318     fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
319 	     file, line, fn);
320   else
321     fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
322 	     file, line);
323   fprintf (stderr, _("Please report this bug.\n"));
324   xexit (EXIT_FAILURE);
325 }
326 
327 /* Support routines.  */
328 
329 void
330 sprint_value (char *buf, valueT val)
331 {
332   if (sizeof (val) <= sizeof (long))
333     {
334       sprintf (buf, "%ld", (long) val);
335       return;
336     }
337   if (sizeof (val) <= sizeof (bfd_vma))
338     {
339       sprintf_vma (buf, val);
340       return;
341     }
342   abort ();
343 }
344 
345 #define HEX_MAX_THRESHOLD	1024
346 #define HEX_MIN_THRESHOLD	-(HEX_MAX_THRESHOLD)
347 
348 static void
349 as_internal_value_out_of_range (char *    prefix,
350 				offsetT   val,
351 				offsetT   min,
352 				offsetT   max,
353 				char *    file,
354 				unsigned  line,
355 				int       bad)
356 {
357   const char * err;
358 
359   if (prefix == NULL)
360     prefix = "";
361 
362   if (val >= min && val <= max)
363     {
364       addressT right = max & -max;
365 
366       if (max <= 1)
367 	abort ();
368 
369       /* xgettext:c-format  */
370       err = _("%s out of domain (%d is not a multiple of %d)");
371       if (bad)
372 	as_bad_where (file, line, err,
373 		      prefix, (int) val, (int) right);
374       else
375 	as_warn_where (file, line, err,
376 		       prefix, (int) val, (int) right);
377       return;
378     }
379 
380   if (   val < HEX_MAX_THRESHOLD
381       && min < HEX_MAX_THRESHOLD
382       && max < HEX_MAX_THRESHOLD
383       && val > HEX_MIN_THRESHOLD
384       && min > HEX_MIN_THRESHOLD
385       && max > HEX_MIN_THRESHOLD)
386     {
387       /* xgettext:c-format  */
388       err = _("%s out of range (%d is not between %d and %d)");
389 
390       if (bad)
391 	as_bad_where (file, line, err,
392 		      prefix, (int) val, (int) min, (int) max);
393       else
394 	as_warn_where (file, line, err,
395 		       prefix, (int) val, (int) min, (int) max);
396     }
397   else
398     {
399       char val_buf [sizeof (val) * 3 + 2];
400       char min_buf [sizeof (val) * 3 + 2];
401       char max_buf [sizeof (val) * 3 + 2];
402 
403       if (sizeof (val) > sizeof (bfd_vma))
404 	abort ();
405 
406       sprintf_vma (val_buf, (bfd_vma) val);
407       sprintf_vma (min_buf, (bfd_vma) min);
408       sprintf_vma (max_buf, (bfd_vma) max);
409 
410       /* xgettext:c-format.  */
411       err = _("%s out of range (0x%s is not between 0x%s and 0x%s)");
412 
413       if (bad)
414 	as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf);
415       else
416 	as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf);
417     }
418 }
419 
420 void
421 as_warn_value_out_of_range (char *   prefix,
422 			   offsetT  value,
423 			   offsetT  min,
424 			   offsetT  max,
425 			   char *   file,
426 			   unsigned line)
427 {
428   as_internal_value_out_of_range (prefix, value, min, max, file, line, 0);
429 }
430 
431 void
432 as_bad_value_out_of_range (char *   prefix,
433 			   offsetT  value,
434 			   offsetT  min,
435 			   offsetT  max,
436 			   char *   file,
437 			   unsigned line)
438 {
439   as_internal_value_out_of_range (prefix, value, min, max, file, line, 1);
440 }
441