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