Rev 5222 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
5222 | serge | 1 | /* messages.c - error reporter - |
6324 | serge | 2 | Copyright (C) 1987-2015 Free Software Foundation, Inc. |
5222 | serge | 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 (char *); |
||
23 | static void as_show_where (void); |
||
24 | static void as_warn_internal (char *, unsigned int, char *); |
||
25 | static void as_bad_internal (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 (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 | as_where (&file, &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 | char *file; |
||
109 | unsigned int line; |
||
110 | |||
111 | as_where (&file, &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 (char *file, unsigned int line, char *buffer) |
||
144 | { |
||
145 | ++warning_count; |
||
146 | |||
147 | if (file == NULL) |
||
148 | as_where (&file, &line); |
||
149 | |||
150 | identify (file); |
||
151 | if (file) |
||
152 | { |
||
153 | if (line != 0) |
||
6324 | serge | 154 | fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer); |
5222 | serge | 155 | else |
6324 | serge | 156 | fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer); |
5222 | serge | 157 | } |
6324 | serge | 158 | else |
159 | fprintf (stderr, "%s%s\n", _("Warning: "), buffer); |
||
5222 | serge | 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 (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 (char *file, unsigned int line, char *buffer) |
||
209 | { |
||
210 | ++error_count; |
||
211 | |||
212 | if (file == NULL) |
||
213 | as_where (&file, &line); |
||
214 | |||
215 | identify (file); |
||
216 | if (file) |
||
217 | { |
||
218 | if (line != 0) |
||
6324 | serge | 219 | fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer); |
5222 | serge | 220 | else |
6324 | serge | 221 | fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer); |
5222 | serge | 222 | } |
6324 | serge | 223 | else |
224 | fprintf (stderr, "%s%s\n", _("Error: "), buffer); |
||
5222 | serge | 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 us 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 (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) |
||
6324 | serge | 298 | fprintf (stderr, _("Assertion failure in %s at %s:%d.\n"), |
5222 | serge | 299 | fn, file, line); |
300 | else |
||
6324 | serge | 301 | fprintf (stderr, _("Assertion failure at %s:%d.\n"), file, line); |
5222 | serge | 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) |
||
6324 | serge | 314 | fprintf (stderr, _("Internal error, aborting at %s:%d in %s\n"), |
5222 | serge | 315 | file, line, fn); |
316 | else |
||
6324 | serge | 317 | fprintf (stderr, _("Internal error, aborting at %s:%d\n"), |
5222 | serge | 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 (char * prefix, |
||
346 | offsetT val, |
||
347 | offsetT min, |
||
348 | offsetT max, |
||
349 | 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 (char * prefix, |
||
418 | offsetT value, |
||
419 | offsetT min, |
||
420 | offsetT max, |
||
421 | 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 (char * prefix, |
||
429 | offsetT value, |
||
430 | offsetT min, |
||
431 | offsetT max, |
||
432 | char * file, |
||
433 | unsigned line) |
||
434 | { |
||
435 | as_internal_value_out_of_range (prefix, value, min, max, file, line, 1); |
||
436 | }>>>=>=>=>=> |