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