Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5222 | serge | 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 | }>>>=>=>=>=> |