Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* messages.c - error reporter - |
2159ac21 | 2 | Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, |
7be1c489 | 3 | 2003, 2004, 2005 |
252b5132 RH |
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 | |
4b4da160 NC |
19 | Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA |
20 | 02110-1301, USA. */ | |
252b5132 RH |
21 | |
22 | #include "as.h" | |
23 | ||
254d758c KH |
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 *); | |
252b5132 | 28 | |
ef99799a | 29 | /* Despite the rest of the comments in this file, (FIXME-SOON), |
5a1964ec NC |
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. */ | |
252b5132 RH |
64 | |
65 | static void | |
254d758c | 66 | identify (char *file) |
252b5132 RH |
67 | { |
68 | static int identified; | |
5a1964ec | 69 | |
252b5132 RH |
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 | ||
ef99799a KH |
85 | /* The number of warnings issued. */ |
86 | static int warning_count; | |
252b5132 | 87 | |
c488923f | 88 | int |
254d758c | 89 | had_warnings (void) |
252b5132 | 90 | { |
5a1964ec | 91 | return warning_count; |
252b5132 RH |
92 | } |
93 | ||
94 | /* Nonzero if we've hit a 'bad error', and should not write an obj file, | |
ef99799a | 95 | and exit with a nonzero error code. */ |
252b5132 RH |
96 | |
97 | static int error_count; | |
98 | ||
c488923f | 99 | int |
254d758c | 100 | had_errors (void) |
252b5132 | 101 | { |
5a1964ec | 102 | return error_count; |
252b5132 RH |
103 | } |
104 | ||
252b5132 RH |
105 | /* Print the current location to stderr. */ |
106 | ||
107 | static void | |
254d758c | 108 | as_show_where (void) |
252b5132 RH |
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 | ||
ef99799a | 119 | /* Like perror(3), but with more info. */ |
252b5132 | 120 | |
c488923f | 121 | void |
254d758c KH |
122 | as_perror (const char *gripe, /* Unpunctuated error theme. */ |
123 | const char *filename) | |
252b5132 RH |
124 | { |
125 | const char *errtxt; | |
5a1964ec | 126 | int saved_errno = errno; |
252b5132 RH |
127 | |
128 | as_show_where (); | |
129 | fprintf (stderr, gripe, filename); | |
5a1964ec | 130 | errno = saved_errno; |
252b5132 | 131 | errtxt = bfd_errmsg (bfd_get_error ()); |
252b5132 RH |
132 | fprintf (stderr, ": %s\n", errtxt); |
133 | errno = 0; | |
252b5132 | 134 | bfd_set_error (bfd_error_no_error); |
252b5132 RH |
135 | } |
136 | ||
ef99799a KH |
137 | /* Send to stderr a string as a warning, and locate warning |
138 | in input file(s). | |
139 | Please only use this for when we have some recovery action. | |
140 | Please explain in string (which may have '\n's) what recovery was | |
141 | done. */ | |
252b5132 RH |
142 | |
143 | #ifdef USE_STDARG | |
c488923f | 144 | void |
ef99799a | 145 | as_tsktsk (const char *format, ...) |
252b5132 RH |
146 | { |
147 | va_list args; | |
148 | ||
149 | as_show_where (); | |
150 | va_start (args, format); | |
151 | vfprintf (stderr, format, args); | |
152 | va_end (args); | |
153 | (void) putc ('\n', stderr); | |
ef99799a | 154 | } |
252b5132 | 155 | #else |
c488923f | 156 | void |
252b5132 RH |
157 | as_tsktsk (format, va_alist) |
158 | const char *format; | |
159 | va_dcl | |
160 | { | |
161 | va_list args; | |
162 | ||
163 | as_show_where (); | |
164 | va_start (args); | |
165 | vfprintf (stderr, format, args); | |
166 | va_end (args); | |
167 | (void) putc ('\n', stderr); | |
ef99799a | 168 | } |
252b5132 RH |
169 | #endif /* not NO_STDARG */ |
170 | ||
171 | /* The common portion of as_warn and as_warn_where. */ | |
172 | ||
173 | static void | |
254d758c | 174 | as_warn_internal (char *file, unsigned int line, char *buffer) |
252b5132 RH |
175 | { |
176 | ++warning_count; | |
177 | ||
178 | if (file == NULL) | |
179 | as_where (&file, &line); | |
180 | ||
181 | identify (file); | |
182 | if (file) | |
183 | fprintf (stderr, "%s:%u: ", file, line); | |
184 | fprintf (stderr, _("Warning: ")); | |
185 | fputs (buffer, stderr); | |
186 | (void) putc ('\n', stderr); | |
187 | #ifndef NO_LISTING | |
188 | listing_warning (buffer); | |
189 | #endif | |
190 | } | |
191 | ||
ef99799a KH |
192 | /* Send to stderr a string as a warning, and locate warning |
193 | in input file(s). | |
194 | Please only use this for when we have some recovery action. | |
195 | Please explain in string (which may have '\n's) what recovery was | |
196 | done. */ | |
252b5132 RH |
197 | |
198 | #ifdef USE_STDARG | |
c488923f | 199 | void |
ef99799a | 200 | as_warn (const char *format, ...) |
252b5132 RH |
201 | { |
202 | va_list args; | |
203 | char buffer[2000]; | |
204 | ||
205 | if (!flag_no_warnings) | |
206 | { | |
207 | va_start (args, format); | |
a9bfff94 | 208 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
209 | va_end (args); |
210 | as_warn_internal ((char *) NULL, 0, buffer); | |
211 | } | |
ef99799a | 212 | } |
252b5132 | 213 | #else |
c488923f | 214 | void |
252b5132 RH |
215 | as_warn (format, va_alist) |
216 | const char *format; | |
217 | va_dcl | |
218 | { | |
219 | va_list args; | |
220 | char buffer[2000]; | |
221 | ||
222 | if (!flag_no_warnings) | |
223 | { | |
224 | va_start (args); | |
a9bfff94 | 225 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
226 | va_end (args); |
227 | as_warn_internal ((char *) NULL, 0, buffer); | |
228 | } | |
ef99799a | 229 | } |
252b5132 RH |
230 | #endif /* not NO_STDARG */ |
231 | ||
ef99799a KH |
232 | /* Like as_bad but the file name and line number are passed in. |
233 | Unfortunately, we have to repeat the function in order to handle | |
234 | the varargs correctly and portably. */ | |
252b5132 RH |
235 | |
236 | #ifdef USE_STDARG | |
c488923f | 237 | void |
ef99799a | 238 | as_warn_where (char *file, unsigned int line, const char *format, ...) |
252b5132 RH |
239 | { |
240 | va_list args; | |
241 | char buffer[2000]; | |
242 | ||
243 | if (!flag_no_warnings) | |
244 | { | |
245 | va_start (args, format); | |
a9bfff94 | 246 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
247 | va_end (args); |
248 | as_warn_internal (file, line, buffer); | |
249 | } | |
ef99799a | 250 | } |
252b5132 | 251 | #else |
c488923f | 252 | void |
252b5132 RH |
253 | as_warn_where (file, line, format, va_alist) |
254 | char *file; | |
255 | unsigned int line; | |
256 | const char *format; | |
257 | va_dcl | |
258 | { | |
259 | va_list args; | |
260 | char buffer[2000]; | |
261 | ||
262 | if (!flag_no_warnings) | |
263 | { | |
264 | va_start (args); | |
a9bfff94 | 265 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
266 | va_end (args); |
267 | as_warn_internal (file, line, buffer); | |
268 | } | |
ef99799a | 269 | } |
252b5132 RH |
270 | #endif /* not NO_STDARG */ |
271 | ||
272 | /* The common portion of as_bad and as_bad_where. */ | |
273 | ||
274 | static void | |
254d758c | 275 | as_bad_internal (char *file, unsigned int line, char *buffer) |
252b5132 RH |
276 | { |
277 | ++error_count; | |
278 | ||
279 | if (file == NULL) | |
280 | as_where (&file, &line); | |
281 | ||
282 | identify (file); | |
283 | if (file) | |
284 | fprintf (stderr, "%s:%u: ", file, line); | |
285 | fprintf (stderr, _("Error: ")); | |
286 | fputs (buffer, stderr); | |
287 | (void) putc ('\n', stderr); | |
288 | #ifndef NO_LISTING | |
289 | listing_error (buffer); | |
290 | #endif | |
291 | } | |
292 | ||
ef99799a KH |
293 | /* Send to stderr a string as a warning, and locate warning in input |
294 | file(s). Please us when there is no recovery, but we want to | |
295 | continue processing but not produce an object file. | |
296 | Please explain in string (which may have '\n's) what recovery was | |
43ad3147 | 297 | done. */ |
252b5132 RH |
298 | |
299 | #ifdef USE_STDARG | |
c488923f | 300 | void |
ef99799a | 301 | as_bad (const char *format, ...) |
252b5132 RH |
302 | { |
303 | va_list args; | |
304 | char buffer[2000]; | |
305 | ||
306 | va_start (args, format); | |
a9bfff94 | 307 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
308 | va_end (args); |
309 | ||
310 | as_bad_internal ((char *) NULL, 0, buffer); | |
311 | } | |
312 | ||
313 | #else | |
c488923f | 314 | void |
252b5132 RH |
315 | as_bad (format, va_alist) |
316 | const char *format; | |
317 | va_dcl | |
318 | { | |
319 | va_list args; | |
320 | char buffer[2000]; | |
321 | ||
322 | va_start (args); | |
a9bfff94 | 323 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
324 | va_end (args); |
325 | ||
326 | as_bad_internal ((char *) NULL, 0, buffer); | |
327 | } | |
328 | #endif /* not NO_STDARG */ | |
329 | ||
ef99799a KH |
330 | /* Like as_bad but the file name and line number are passed in. |
331 | Unfortunately, we have to repeat the function in order to handle | |
332 | the varargs correctly and portably. */ | |
252b5132 RH |
333 | |
334 | #ifdef USE_STDARG | |
c488923f | 335 | void |
ef99799a | 336 | as_bad_where (char *file, unsigned int line, const char *format, ...) |
252b5132 RH |
337 | { |
338 | va_list args; | |
339 | char buffer[2000]; | |
340 | ||
341 | va_start (args, format); | |
a9bfff94 | 342 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
343 | va_end (args); |
344 | ||
345 | as_bad_internal (file, line, buffer); | |
346 | } | |
347 | ||
348 | #else | |
c488923f | 349 | void |
252b5132 RH |
350 | as_bad_where (file, line, format, va_alist) |
351 | char *file; | |
352 | unsigned int line; | |
353 | const char *format; | |
354 | va_dcl | |
355 | { | |
356 | va_list args; | |
357 | char buffer[2000]; | |
358 | ||
359 | va_start (args); | |
a9bfff94 | 360 | vsnprintf (buffer, sizeof (buffer), format, args); |
252b5132 RH |
361 | va_end (args); |
362 | ||
363 | as_bad_internal (file, line, buffer); | |
364 | } | |
365 | #endif /* not NO_STDARG */ | |
366 | ||
ef99799a KH |
367 | /* Send to stderr a string as a fatal message, and print location of |
368 | error in input file(s). | |
369 | Please only use this for when we DON'T have some recovery action. | |
370 | It xexit()s with a warning status. */ | |
252b5132 RH |
371 | |
372 | #ifdef USE_STDARG | |
c488923f | 373 | void |
ef99799a | 374 | as_fatal (const char *format, ...) |
252b5132 RH |
375 | { |
376 | va_list args; | |
377 | ||
378 | as_show_where (); | |
379 | va_start (args, format); | |
380 | fprintf (stderr, _("Fatal error: ")); | |
381 | vfprintf (stderr, format, args); | |
382 | (void) putc ('\n', stderr); | |
383 | va_end (args); | |
d4887adc NC |
384 | /* Delete the output file, if it exists. This will prevent make from |
385 | thinking that a file was created and hence does not need rebuilding. */ | |
386 | if (out_file_name != NULL) | |
bb14f524 | 387 | unlink_if_ordinary (out_file_name); |
252b5132 | 388 | xexit (EXIT_FAILURE); |
ef99799a | 389 | } |
252b5132 | 390 | #else |
c488923f | 391 | void |
252b5132 RH |
392 | as_fatal (format, va_alist) |
393 | char *format; | |
394 | va_dcl | |
395 | { | |
396 | va_list args; | |
397 | ||
398 | as_show_where (); | |
399 | va_start (args); | |
400 | fprintf (stderr, _("Fatal error: ")); | |
401 | vfprintf (stderr, format, args); | |
402 | (void) putc ('\n', stderr); | |
403 | va_end (args); | |
404 | xexit (EXIT_FAILURE); | |
ef99799a | 405 | } |
252b5132 RH |
406 | #endif /* not NO_STDARG */ |
407 | ||
ef99799a KH |
408 | /* Indicate assertion failure. |
409 | Arguments: Filename, line number, optional function name. */ | |
252b5132 RH |
410 | |
411 | void | |
254d758c | 412 | as_assert (const char *file, int line, const char *fn) |
252b5132 RH |
413 | { |
414 | as_show_where (); | |
415 | fprintf (stderr, _("Internal error!\n")); | |
416 | if (fn) | |
417 | fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), | |
418 | fn, file, line); | |
419 | else | |
420 | fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); | |
421 | fprintf (stderr, _("Please report this bug.\n")); | |
422 | xexit (EXIT_FAILURE); | |
423 | } | |
424 | ||
425 | /* as_abort: Print a friendly message saying how totally hosed we are, | |
426 | and exit without producing a core file. */ | |
ef99799a | 427 | |
252b5132 | 428 | void |
254d758c | 429 | as_abort (const char *file, int line, const char *fn) |
252b5132 RH |
430 | { |
431 | as_show_where (); | |
432 | if (fn) | |
433 | fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), | |
434 | file, line, fn); | |
435 | else | |
436 | fprintf (stderr, _("Internal error, aborting at %s line %d\n"), | |
437 | file, line); | |
438 | fprintf (stderr, _("Please report this bug.\n")); | |
439 | xexit (EXIT_FAILURE); | |
440 | } | |
441 | ||
442 | /* Support routines. */ | |
443 | ||
252b5132 | 444 | void |
254d758c | 445 | sprint_value (char *buf, valueT val) |
252b5132 RH |
446 | { |
447 | if (sizeof (val) <= sizeof (long)) | |
448 | { | |
449 | sprintf (buf, "%ld", (long) val); | |
450 | return; | |
451 | } | |
252b5132 RH |
452 | if (sizeof (val) <= sizeof (bfd_vma)) |
453 | { | |
454 | sprintf_vma (buf, val); | |
455 | return; | |
456 | } | |
252b5132 RH |
457 | abort (); |
458 | } | |
e5976317 NC |
459 | |
460 | #define HEX_MAX_THRESHOLD 1024 | |
461 | #define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD) | |
462 | ||
463 | static void | |
464 | as_internal_value_out_of_range (char * prefix, | |
465 | offsetT val, | |
466 | offsetT min, | |
467 | offsetT max, | |
468 | char * file, | |
469 | unsigned line, | |
470 | int bad) | |
471 | { | |
472 | const char * err; | |
473 | ||
474 | if (prefix == NULL) | |
475 | prefix = ""; | |
476 | ||
e5976317 NC |
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) | |
e5976317 NC |
483 | { |
484 | /* xgettext:c-format */ | |
485 | err = _("%s out of range (%d is not between %d and %d)"); | |
486 | ||
487 | if (bad) | |
2159ac21 AM |
488 | as_bad_where (file, line, err, |
489 | prefix, (int) val, (int) min, (int) max); | |
e5976317 | 490 | else |
2159ac21 AM |
491 | as_warn_where (file, line, err, |
492 | prefix, (int) val, (int) min, (int) max); | |
e5976317 | 493 | } |
e5976317 NC |
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 | } | |
e5976317 NC |
515 | } |
516 | ||
517 | void | |
518 | as_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 | ||
528 | void | |
529 | as_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 | } |