]>
Commit | Line | Data |
---|---|---|
252b5132 | 1 | /* messages.c - error reporter - |
2159ac21 AM |
2 | Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, |
3 | 2003, 2004 | |
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 | |
19 | Software Foundation, 59 Temple Place - Suite 330, Boston, MA | |
c488923f | 20 | 02111-1307, 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 RH |
153 | #ifdef BFD_ASSEMBLER |
154 | errtxt = bfd_errmsg (bfd_get_error ()); | |
155 | #else | |
156 | errtxt = xstrerror (errno); | |
157 | #endif | |
158 | fprintf (stderr, ": %s\n", errtxt); | |
159 | errno = 0; | |
160 | #ifdef BFD_ASSEMBLER | |
161 | bfd_set_error (bfd_error_no_error); | |
162 | #endif | |
163 | } | |
164 | ||
ef99799a KH |
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. */ | |
252b5132 RH |
170 | |
171 | #ifdef USE_STDARG | |
c488923f | 172 | void |
ef99799a | 173 | as_tsktsk (const char *format, ...) |
252b5132 RH |
174 | { |
175 | va_list args; | |
176 | ||
177 | as_show_where (); | |
178 | va_start (args, format); | |
179 | vfprintf (stderr, format, args); | |
180 | va_end (args); | |
181 | (void) putc ('\n', stderr); | |
ef99799a | 182 | } |
252b5132 | 183 | #else |
c488923f | 184 | void |
252b5132 RH |
185 | as_tsktsk (format, va_alist) |
186 | const char *format; | |
187 | va_dcl | |
188 | { | |
189 | va_list args; | |
190 | ||
191 | as_show_where (); | |
192 | va_start (args); | |
193 | vfprintf (stderr, format, args); | |
194 | va_end (args); | |
195 | (void) putc ('\n', stderr); | |
ef99799a | 196 | } |
252b5132 RH |
197 | #endif /* not NO_STDARG */ |
198 | ||
199 | /* The common portion of as_warn and as_warn_where. */ | |
200 | ||
201 | static void | |
254d758c | 202 | as_warn_internal (char *file, unsigned int line, char *buffer) |
252b5132 RH |
203 | { |
204 | ++warning_count; | |
205 | ||
206 | if (file == NULL) | |
207 | as_where (&file, &line); | |
208 | ||
209 | identify (file); | |
210 | if (file) | |
211 | fprintf (stderr, "%s:%u: ", file, line); | |
212 | fprintf (stderr, _("Warning: ")); | |
213 | fputs (buffer, stderr); | |
214 | (void) putc ('\n', stderr); | |
215 | #ifndef NO_LISTING | |
216 | listing_warning (buffer); | |
217 | #endif | |
218 | } | |
219 | ||
ef99799a KH |
220 | /* Send to stderr a string as a warning, and locate warning |
221 | in input file(s). | |
222 | Please only use this for when we have some recovery action. | |
223 | Please explain in string (which may have '\n's) what recovery was | |
224 | done. */ | |
252b5132 RH |
225 | |
226 | #ifdef USE_STDARG | |
c488923f | 227 | void |
ef99799a | 228 | as_warn (const char *format, ...) |
252b5132 RH |
229 | { |
230 | va_list args; | |
231 | char buffer[2000]; | |
232 | ||
233 | if (!flag_no_warnings) | |
234 | { | |
235 | va_start (args, format); | |
236 | vsprintf (buffer, format, args); | |
237 | va_end (args); | |
238 | as_warn_internal ((char *) NULL, 0, buffer); | |
239 | } | |
ef99799a | 240 | } |
252b5132 | 241 | #else |
c488923f | 242 | void |
252b5132 RH |
243 | as_warn (format, va_alist) |
244 | const char *format; | |
245 | va_dcl | |
246 | { | |
247 | va_list args; | |
248 | char buffer[2000]; | |
249 | ||
250 | if (!flag_no_warnings) | |
251 | { | |
252 | va_start (args); | |
253 | vsprintf (buffer, format, args); | |
254 | va_end (args); | |
255 | as_warn_internal ((char *) NULL, 0, buffer); | |
256 | } | |
ef99799a | 257 | } |
252b5132 RH |
258 | #endif /* not NO_STDARG */ |
259 | ||
ef99799a KH |
260 | /* Like as_bad but the file name and line number are passed in. |
261 | Unfortunately, we have to repeat the function in order to handle | |
262 | the varargs correctly and portably. */ | |
252b5132 RH |
263 | |
264 | #ifdef USE_STDARG | |
c488923f | 265 | void |
ef99799a | 266 | as_warn_where (char *file, unsigned int line, const char *format, ...) |
252b5132 RH |
267 | { |
268 | va_list args; | |
269 | char buffer[2000]; | |
270 | ||
271 | if (!flag_no_warnings) | |
272 | { | |
273 | va_start (args, format); | |
274 | vsprintf (buffer, format, args); | |
275 | va_end (args); | |
276 | as_warn_internal (file, line, buffer); | |
277 | } | |
ef99799a | 278 | } |
252b5132 | 279 | #else |
c488923f | 280 | void |
252b5132 RH |
281 | as_warn_where (file, line, format, va_alist) |
282 | char *file; | |
283 | unsigned int line; | |
284 | const char *format; | |
285 | va_dcl | |
286 | { | |
287 | va_list args; | |
288 | char buffer[2000]; | |
289 | ||
290 | if (!flag_no_warnings) | |
291 | { | |
292 | va_start (args); | |
293 | vsprintf (buffer, format, args); | |
294 | va_end (args); | |
295 | as_warn_internal (file, line, buffer); | |
296 | } | |
ef99799a | 297 | } |
252b5132 RH |
298 | #endif /* not NO_STDARG */ |
299 | ||
300 | /* The common portion of as_bad and as_bad_where. */ | |
301 | ||
302 | static void | |
254d758c | 303 | as_bad_internal (char *file, unsigned int line, char *buffer) |
252b5132 RH |
304 | { |
305 | ++error_count; | |
306 | ||
307 | if (file == NULL) | |
308 | as_where (&file, &line); | |
309 | ||
310 | identify (file); | |
311 | if (file) | |
312 | fprintf (stderr, "%s:%u: ", file, line); | |
313 | fprintf (stderr, _("Error: ")); | |
314 | fputs (buffer, stderr); | |
315 | (void) putc ('\n', stderr); | |
316 | #ifndef NO_LISTING | |
317 | listing_error (buffer); | |
318 | #endif | |
319 | } | |
320 | ||
ef99799a KH |
321 | /* Send to stderr a string as a warning, and locate warning in input |
322 | file(s). Please us when there is no recovery, but we want to | |
323 | continue processing but not produce an object file. | |
324 | Please explain in string (which may have '\n's) what recovery was | |
43ad3147 | 325 | done. */ |
252b5132 RH |
326 | |
327 | #ifdef USE_STDARG | |
c488923f | 328 | void |
ef99799a | 329 | as_bad (const char *format, ...) |
252b5132 RH |
330 | { |
331 | va_list args; | |
332 | char buffer[2000]; | |
333 | ||
334 | va_start (args, format); | |
335 | vsprintf (buffer, format, args); | |
336 | va_end (args); | |
337 | ||
338 | as_bad_internal ((char *) NULL, 0, buffer); | |
339 | } | |
340 | ||
341 | #else | |
c488923f | 342 | void |
252b5132 RH |
343 | as_bad (format, va_alist) |
344 | const char *format; | |
345 | va_dcl | |
346 | { | |
347 | va_list args; | |
348 | char buffer[2000]; | |
349 | ||
350 | va_start (args); | |
351 | vsprintf (buffer, format, args); | |
352 | va_end (args); | |
353 | ||
354 | as_bad_internal ((char *) NULL, 0, buffer); | |
355 | } | |
356 | #endif /* not NO_STDARG */ | |
357 | ||
ef99799a KH |
358 | /* Like as_bad but the file name and line number are passed in. |
359 | Unfortunately, we have to repeat the function in order to handle | |
360 | the varargs correctly and portably. */ | |
252b5132 RH |
361 | |
362 | #ifdef USE_STDARG | |
c488923f | 363 | void |
ef99799a | 364 | as_bad_where (char *file, unsigned int line, const char *format, ...) |
252b5132 RH |
365 | { |
366 | va_list args; | |
367 | char buffer[2000]; | |
368 | ||
369 | va_start (args, format); | |
370 | vsprintf (buffer, format, args); | |
371 | va_end (args); | |
372 | ||
373 | as_bad_internal (file, line, buffer); | |
374 | } | |
375 | ||
376 | #else | |
c488923f | 377 | void |
252b5132 RH |
378 | as_bad_where (file, line, format, va_alist) |
379 | char *file; | |
380 | unsigned int line; | |
381 | const char *format; | |
382 | va_dcl | |
383 | { | |
384 | va_list args; | |
385 | char buffer[2000]; | |
386 | ||
387 | va_start (args); | |
388 | vsprintf (buffer, format, args); | |
389 | va_end (args); | |
390 | ||
391 | as_bad_internal (file, line, buffer); | |
392 | } | |
393 | #endif /* not NO_STDARG */ | |
394 | ||
ef99799a KH |
395 | /* Send to stderr a string as a fatal message, and print location of |
396 | error in input file(s). | |
397 | Please only use this for when we DON'T have some recovery action. | |
398 | It xexit()s with a warning status. */ | |
252b5132 RH |
399 | |
400 | #ifdef USE_STDARG | |
c488923f | 401 | void |
ef99799a | 402 | as_fatal (const char *format, ...) |
252b5132 RH |
403 | { |
404 | va_list args; | |
405 | ||
406 | as_show_where (); | |
407 | va_start (args, format); | |
408 | fprintf (stderr, _("Fatal error: ")); | |
409 | vfprintf (stderr, format, args); | |
410 | (void) putc ('\n', stderr); | |
411 | va_end (args); | |
d4887adc NC |
412 | /* Delete the output file, if it exists. This will prevent make from |
413 | thinking that a file was created and hence does not need rebuilding. */ | |
414 | if (out_file_name != NULL) | |
415 | unlink (out_file_name); | |
252b5132 | 416 | xexit (EXIT_FAILURE); |
ef99799a | 417 | } |
252b5132 | 418 | #else |
c488923f | 419 | void |
252b5132 RH |
420 | as_fatal (format, va_alist) |
421 | char *format; | |
422 | va_dcl | |
423 | { | |
424 | va_list args; | |
425 | ||
426 | as_show_where (); | |
427 | va_start (args); | |
428 | fprintf (stderr, _("Fatal error: ")); | |
429 | vfprintf (stderr, format, args); | |
430 | (void) putc ('\n', stderr); | |
431 | va_end (args); | |
432 | xexit (EXIT_FAILURE); | |
ef99799a | 433 | } |
252b5132 RH |
434 | #endif /* not NO_STDARG */ |
435 | ||
ef99799a KH |
436 | /* Indicate assertion failure. |
437 | Arguments: Filename, line number, optional function name. */ | |
252b5132 RH |
438 | |
439 | void | |
254d758c | 440 | as_assert (const char *file, int line, const char *fn) |
252b5132 RH |
441 | { |
442 | as_show_where (); | |
443 | fprintf (stderr, _("Internal error!\n")); | |
444 | if (fn) | |
445 | fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), | |
446 | fn, file, line); | |
447 | else | |
448 | fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); | |
449 | fprintf (stderr, _("Please report this bug.\n")); | |
450 | xexit (EXIT_FAILURE); | |
451 | } | |
452 | ||
453 | /* as_abort: Print a friendly message saying how totally hosed we are, | |
454 | and exit without producing a core file. */ | |
ef99799a | 455 | |
252b5132 | 456 | void |
254d758c | 457 | as_abort (const char *file, int line, const char *fn) |
252b5132 RH |
458 | { |
459 | as_show_where (); | |
460 | if (fn) | |
461 | fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), | |
462 | file, line, fn); | |
463 | else | |
464 | fprintf (stderr, _("Internal error, aborting at %s line %d\n"), | |
465 | file, line); | |
466 | fprintf (stderr, _("Please report this bug.\n")); | |
467 | xexit (EXIT_FAILURE); | |
468 | } | |
469 | ||
470 | /* Support routines. */ | |
471 | ||
472 | void | |
254d758c | 473 | fprint_value (FILE *file, valueT val) |
252b5132 RH |
474 | { |
475 | if (sizeof (val) <= sizeof (long)) | |
476 | { | |
477 | fprintf (file, "%ld", (long) val); | |
478 | return; | |
479 | } | |
480 | #ifdef BFD_ASSEMBLER | |
481 | if (sizeof (val) <= sizeof (bfd_vma)) | |
482 | { | |
483 | fprintf_vma (file, val); | |
484 | return; | |
485 | } | |
486 | #endif | |
487 | abort (); | |
488 | } | |
489 | ||
490 | void | |
254d758c | 491 | sprint_value (char *buf, valueT val) |
252b5132 RH |
492 | { |
493 | if (sizeof (val) <= sizeof (long)) | |
494 | { | |
495 | sprintf (buf, "%ld", (long) val); | |
496 | return; | |
497 | } | |
498 | #ifdef BFD_ASSEMBLER | |
499 | if (sizeof (val) <= sizeof (bfd_vma)) | |
500 | { | |
501 | sprintf_vma (buf, val); | |
502 | return; | |
503 | } | |
504 | #endif | |
505 | abort (); | |
506 | } | |
e5976317 NC |
507 | |
508 | #define HEX_MAX_THRESHOLD 1024 | |
509 | #define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD) | |
510 | ||
511 | static void | |
512 | as_internal_value_out_of_range (char * prefix, | |
513 | offsetT val, | |
514 | offsetT min, | |
515 | offsetT max, | |
516 | char * file, | |
517 | unsigned line, | |
518 | int bad) | |
519 | { | |
520 | const char * err; | |
521 | ||
522 | if (prefix == NULL) | |
523 | prefix = ""; | |
524 | ||
525 | #ifdef BFD_ASSEMBLER | |
526 | if ( val < HEX_MAX_THRESHOLD | |
527 | && min < HEX_MAX_THRESHOLD | |
528 | && max < HEX_MAX_THRESHOLD | |
529 | && val > HEX_MIN_THRESHOLD | |
530 | && min > HEX_MIN_THRESHOLD | |
531 | && max > HEX_MIN_THRESHOLD) | |
532 | #endif | |
533 | { | |
534 | /* xgettext:c-format */ | |
535 | err = _("%s out of range (%d is not between %d and %d)"); | |
536 | ||
537 | if (bad) | |
2159ac21 AM |
538 | as_bad_where (file, line, err, |
539 | prefix, (int) val, (int) min, (int) max); | |
e5976317 | 540 | else |
2159ac21 AM |
541 | as_warn_where (file, line, err, |
542 | prefix, (int) val, (int) min, (int) max); | |
e5976317 NC |
543 | } |
544 | #ifdef BFD_ASSEMBLER | |
545 | else | |
546 | { | |
547 | char val_buf [sizeof (val) * 3 + 2]; | |
548 | char min_buf [sizeof (val) * 3 + 2]; | |
549 | char max_buf [sizeof (val) * 3 + 2]; | |
550 | ||
551 | if (sizeof (val) > sizeof (bfd_vma)) | |
552 | abort (); | |
553 | ||
554 | sprintf_vma (val_buf, val); | |
555 | sprintf_vma (min_buf, min); | |
556 | sprintf_vma (max_buf, max); | |
557 | ||
558 | /* xgettext:c-format. */ | |
559 | err = _("%s out of range (0x%s is not between 0x%s and 0x%s)"); | |
560 | ||
561 | if (bad) | |
562 | as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf); | |
563 | else | |
564 | as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf); | |
565 | } | |
566 | #endif | |
567 | } | |
568 | ||
569 | void | |
570 | as_warn_value_out_of_range (char * prefix, | |
571 | offsetT value, | |
572 | offsetT min, | |
573 | offsetT max, | |
574 | char * file, | |
575 | unsigned line) | |
576 | { | |
577 | as_internal_value_out_of_range (prefix, value, min, max, file, line, 0); | |
578 | } | |
579 | ||
580 | void | |
581 | as_bad_value_out_of_range (char * prefix, | |
582 | offsetT value, | |
583 | offsetT min, | |
584 | offsetT max, | |
585 | char * file, | |
586 | unsigned line) | |
587 | { | |
588 | as_internal_value_out_of_range (prefix, value, min, max, file, line, 1); | |
589 | } |