Automatic date update in version.in
[deliverable/binutils-gdb.git] / gas / messages.c
1 /* messages.c - error reporter -
2 Copyright (C) 1987-2021 Free Software Foundation, Inc.
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 #include <signal.h>
22
23 /* If the system doesn't provide strsignal, we get it defined in
24 libiberty but no declaration is supplied. Because, reasons. */
25 #if !defined (HAVE_STRSIGNAL) && !defined (strsignal)
26 extern const char *strsignal (int);
27 #endif
28
29 static void identify (const char *);
30 static void as_show_where (void);
31 static void as_warn_internal (const char *, unsigned int, char *);
32 static void as_bad_internal (const char *, unsigned int, char *);
33 static void signal_crash (int) ATTRIBUTE_NORETURN;
34
35 /* Despite the rest of the comments in this file, (FIXME-SOON),
36 here is the current scheme for error messages etc:
37
38 as_fatal() is used when gas is quite confused and
39 continuing the assembly is pointless. In this case we
40 exit immediately with error status.
41
42 as_bad() is used to mark errors that result in what we
43 presume to be a useless object file. Say, we ignored
44 something that might have been vital. If we see any of
45 these, assembly will continue to the end of the source,
46 no object file will be produced, and we will terminate
47 with error status. The new option, -Z, tells us to
48 produce an object file anyway but we still exit with
49 error status. The assumption here is that you don't want
50 this object file but we could be wrong.
51
52 as_warn() is used when we have an error from which we
53 have a plausible error recovery. eg, masking the top
54 bits of a constant that is longer than will fit in the
55 destination. In this case we will continue to assemble
56 the source, although we may have made a bad assumption,
57 and we will produce an object file and return normal exit
58 status (ie, no error). The new option -X tells us to
59 treat all as_warn() errors as as_bad() errors. That is,
60 no object file will be produced and we will exit with
61 error status. The idea here is that we don't kill an
62 entire make because of an error that we knew how to
63 correct. On the other hand, sometimes you might want to
64 stop the make at these points.
65
66 as_tsktsk() is used when we see a minor error for which
67 our error recovery action is almost certainly correct.
68 In this case, we print a message and then assembly
69 continues as though no error occurred.
70
71 as_abort () is used for logic failure (assert or abort, signal).
72 */
73
74 static void
75 identify (const char *file)
76 {
77 static int identified;
78
79 if (identified)
80 return;
81 identified++;
82
83 if (!file)
84 {
85 unsigned int x;
86 file = as_where (&x);
87 }
88
89 if (file)
90 fprintf (stderr, "%s: ", file);
91 fprintf (stderr, _("Assembler messages:\n"));
92 }
93
94 /* The number of warnings issued. */
95 static int warning_count;
96
97 int
98 had_warnings (void)
99 {
100 return warning_count;
101 }
102
103 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
104 and exit with a nonzero error code. */
105
106 static int error_count;
107
108 int
109 had_errors (void)
110 {
111 return error_count;
112 }
113
114 /* Print the current location to stderr. */
115
116 static void
117 as_show_where (void)
118 {
119 const char *file;
120 unsigned int line;
121
122 file = as_where (&line);
123 identify (file);
124 if (file)
125 {
126 if (line != 0)
127 fprintf (stderr, "%s:%u: ", file, line);
128 else
129 fprintf (stderr, "%s: ", file);
130 }
131 }
132
133 /* Send to stderr a string as a warning, and locate warning
134 in input file(s).
135 Please only use this for when we have some recovery action.
136 Please explain in string (which may have '\n's) what recovery was
137 done. */
138
139 void
140 as_tsktsk (const char *format, ...)
141 {
142 va_list args;
143
144 as_show_where ();
145 va_start (args, format);
146 vfprintf (stderr, format, args);
147 va_end (args);
148 (void) putc ('\n', stderr);
149 }
150
151 /* The common portion of as_warn and as_warn_where. */
152
153 static void
154 as_warn_internal (const char *file, unsigned int line, char *buffer)
155 {
156 ++warning_count;
157
158 if (file == NULL)
159 file = as_where (&line);
160
161 identify (file);
162 if (file)
163 {
164 if (line != 0)
165 fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer);
166 else
167 fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer);
168 }
169 else
170 fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
171 #ifndef NO_LISTING
172 listing_warning (buffer);
173 #endif
174 }
175
176 /* Send to stderr a string as a warning, and locate warning
177 in input file(s).
178 Please only use this for when we have some recovery action.
179 Please explain in string (which may have '\n's) what recovery was
180 done. */
181
182 void
183 as_warn (const char *format, ...)
184 {
185 va_list args;
186 char buffer[2000];
187
188 if (!flag_no_warnings)
189 {
190 va_start (args, format);
191 vsnprintf (buffer, sizeof (buffer), format, args);
192 va_end (args);
193 as_warn_internal ((char *) NULL, 0, buffer);
194 }
195 }
196
197 /* Like as_bad but the file name and line number are passed in.
198 Unfortunately, we have to repeat the function in order to handle
199 the varargs correctly and portably. */
200
201 void
202 as_warn_where (const char *file, unsigned int line, const char *format, ...)
203 {
204 va_list args;
205 char buffer[2000];
206
207 if (!flag_no_warnings)
208 {
209 va_start (args, format);
210 vsnprintf (buffer, sizeof (buffer), format, args);
211 va_end (args);
212 as_warn_internal (file, line, buffer);
213 }
214 }
215
216 /* The common portion of as_bad and as_bad_where. */
217
218 static void
219 as_bad_internal (const char *file, unsigned int line, char *buffer)
220 {
221 ++error_count;
222
223 if (file == NULL)
224 file = as_where (&line);
225
226 identify (file);
227 if (file)
228 {
229 if (line != 0)
230 fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer);
231 else
232 fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer);
233 }
234 else
235 fprintf (stderr, "%s%s\n", _("Error: "), buffer);
236 #ifndef NO_LISTING
237 listing_error (buffer);
238 #endif
239 }
240
241 /* Send to stderr a string as a warning, and locate warning in input
242 file(s). Please use when there is no recovery, but we want to
243 continue processing but not produce an object file.
244 Please explain in string (which may have '\n's) what recovery was
245 done. */
246
247 void
248 as_bad (const char *format, ...)
249 {
250 va_list args;
251 char buffer[2000];
252
253 va_start (args, format);
254 vsnprintf (buffer, sizeof (buffer), format, args);
255 va_end (args);
256
257 as_bad_internal ((char *) NULL, 0, buffer);
258 }
259
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. */
263
264 void
265 as_bad_where (const char *file, unsigned int line, const char *format, ...)
266 {
267 va_list args;
268 char buffer[2000];
269
270 va_start (args, format);
271 vsnprintf (buffer, sizeof (buffer), format, args);
272 va_end (args);
273
274 as_bad_internal (file, line, buffer);
275 }
276
277 /* Send to stderr a string as a fatal message, and print location of
278 error in input file(s).
279 Please only use this for when we DON'T have some recovery action.
280 It xexit()s with a warning status. */
281
282 void
283 as_fatal (const char *format, ...)
284 {
285 va_list args;
286
287 as_show_where ();
288 va_start (args, format);
289 fprintf (stderr, _("Fatal error: "));
290 vfprintf (stderr, format, args);
291 (void) putc ('\n', stderr);
292 va_end (args);
293 /* Delete the output file, if it exists. This will prevent make from
294 thinking that a file was created and hence does not need rebuilding. */
295 if (out_file_name != NULL)
296 unlink_if_ordinary (out_file_name);
297 xexit (EXIT_FAILURE);
298 }
299
300 /* Indicate internal constency error.
301 Arguments: Filename, line number, optional function name.
302 FILENAME may be NULL, which we use for crash-via-signal. */
303
304 void
305 as_abort (const char *file, int line, const char *fn)
306 {
307 as_show_where ();
308
309 if (!file)
310 fprintf (stderr, _("Internal error (%s).\n"), fn ? fn : "unknown");
311 else if (fn)
312 fprintf (stderr, _("Internal error in %s at %s:%d.\n"), fn, file, line);
313 else
314 fprintf (stderr, _("Internal error at %s:%d.\n"), file, line);
315
316 fprintf (stderr, _("Please report this bug.\n"));
317
318 xexit (EXIT_FAILURE);
319 }
320
321 /* Handler for fatal signals, such as SIGSEGV. */
322
323 static void
324 signal_crash (int signo)
325 {
326 /* Reset, to prevent unbounded recursion. */
327 signal (signo, SIG_DFL);
328
329 as_abort (NULL, 0, strsignal (signo));
330 }
331
332 /* Register signal handlers, for less abrubt crashes. */
333
334 void
335 signal_init (void)
336 {
337 #ifdef SIGSEGV
338 signal (SIGSEGV, signal_crash);
339 #endif
340 #ifdef SIGILL
341 signal (SIGILL, signal_crash);
342 #endif
343 #ifdef SIGBUS
344 signal (SIGBUS, signal_crash);
345 #endif
346 #ifdef SIGABRT
347 signal (SIGABRT, signal_crash);
348 #endif
349 #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
350 signal (SIGIOT, signal_crash);
351 #endif
352 #ifdef SIGFPE
353 signal (SIGFPE, signal_crash);
354 #endif
355 }
356
357 /* Support routines. */
358
359 #define HEX_MAX_THRESHOLD 1024
360 #define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD)
361
362 static void
363 as_internal_value_out_of_range (const char *prefix,
364 offsetT val,
365 offsetT min,
366 offsetT max,
367 const char *file,
368 unsigned line,
369 int bad)
370 {
371 const char * err;
372
373 if (prefix == NULL)
374 prefix = "";
375
376 if (val >= min && val <= max)
377 {
378 addressT right = max & -max;
379
380 if (max <= 1)
381 abort ();
382
383 /* xgettext:c-format */
384 err = _("%s out of domain (%" BFD_VMA_FMT "d is not a multiple of %" \
385 BFD_VMA_FMT "d)");
386 if (bad)
387 as_bad_where (file, line, err, prefix, val, right);
388 else
389 as_warn_where (file, line, err, prefix, val, right);
390 return;
391 }
392
393 if ( val < HEX_MAX_THRESHOLD
394 && min < HEX_MAX_THRESHOLD
395 && max < HEX_MAX_THRESHOLD
396 && val > HEX_MIN_THRESHOLD
397 && min > HEX_MIN_THRESHOLD
398 && max > HEX_MIN_THRESHOLD)
399 {
400 /* xgettext:c-format */
401 err = _("%s out of range (%" BFD_VMA_FMT "d is not between %" \
402 BFD_VMA_FMT "d and %" BFD_VMA_FMT "d)");
403
404 if (bad)
405 as_bad_where (file, line, err, prefix, val, min, max);
406 else
407 as_warn_where (file, line, err, prefix, val, min, max);
408 }
409 else
410 {
411 char val_buf [sizeof (val) * 3 + 2];
412 char min_buf [sizeof (val) * 3 + 2];
413 char max_buf [sizeof (val) * 3 + 2];
414
415 if (sizeof (val) > sizeof (bfd_vma))
416 abort ();
417
418 sprintf_vma (val_buf, (bfd_vma) val);
419 sprintf_vma (min_buf, (bfd_vma) min);
420 sprintf_vma (max_buf, (bfd_vma) max);
421
422 /* xgettext:c-format. */
423 err = _("%s out of range (0x%s is not between 0x%s and 0x%s)");
424
425 if (bad)
426 as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf);
427 else
428 as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf);
429 }
430 }
431
432 void
433 as_warn_value_out_of_range (const char *prefix,
434 offsetT value,
435 offsetT min,
436 offsetT max,
437 const char *file,
438 unsigned line)
439 {
440 as_internal_value_out_of_range (prefix, value, min, max, file, line, 0);
441 }
442
443 void
444 as_bad_value_out_of_range (const char *prefix,
445 offsetT value,
446 offsetT min,
447 offsetT max,
448 const char *file,
449 unsigned line)
450 {
451 as_internal_value_out_of_range (prefix, value, min, max, file, line, 1);
452 }
This page took 0.039426 seconds and 4 git commands to generate.