1 /* messages.c - error reporter -
2 Copyright (C) 1987-2023 Free Software Foundation, Inc.
3 This file is part of GAS, the GNU Assembler.
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)
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.
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
24 /* If the system doesn't provide strsignal, we get it defined in
25 libiberty but no declaration is supplied. Because, reasons. */
26 #if !defined (HAVE_STRSIGNAL) && !defined (strsignal)
27 extern const char *strsignal (int);
30 static void identify (const char *);
31 static void as_show_where (void);
32 static void as_warn_internal (const char *, unsigned int, char *);
33 static void as_bad_internal (const char *, unsigned int, char *);
34 static void signal_crash (int) ATTRIBUTE_NORETURN
;
36 /* Despite the rest of the comments in this file, (FIXME-SOON),
37 here is the current scheme for error messages etc:
39 as_fatal() is used when gas is quite confused and
40 continuing the assembly is pointless. In this case we
41 exit immediately with error status.
43 as_bad() is used to mark errors that result in what we
44 presume to be a useless object file. Say, we ignored
45 something that might have been vital. If we see any of
46 these, assembly will continue to the end of the source,
47 no object file will be produced, and we will terminate
48 with error status. The new option, -Z, tells us to
49 produce an object file anyway but we still exit with
50 error status. The assumption here is that you don't want
51 this object file but we could be wrong.
53 as_warn() is used when we have an error from which we
54 have a plausible error recovery. eg, masking the top
55 bits of a constant that is longer than will fit in the
56 destination. In this case we will continue to assemble
57 the source, although we may have made a bad assumption,
58 and we will produce an object file and return normal exit
59 status (ie, no error). The new option -X tells us to
60 treat all as_warn() errors as as_bad() errors. That is,
61 no object file will be produced and we will exit with
62 error status. The idea here is that we don't kill an
63 entire make because of an error that we knew how to
64 correct. On the other hand, sometimes you might want to
65 stop the make at these points.
67 as_tsktsk() is used when we see a minor error for which
68 our error recovery action is almost certainly correct.
69 In this case, we print a message and then assembly
70 continues as though no error occurred.
72 as_abort () is used for logic failure (assert or abort, signal).
76 identify (const char *file
)
78 static int identified
;
91 fprintf (stderr
, "%s: ", file
);
92 fprintf (stderr
, _("Assembler messages:\n"));
95 /* The number of warnings issued. */
96 static int warning_count
;
101 return warning_count
;
104 /* Nonzero if we've hit a 'bad error', and should not write an obj file,
105 and exit with a nonzero error code. */
107 static int error_count
;
115 /* Print the current location to stderr. */
123 file
= as_where_top (&line
);
128 fprintf (stderr
, "%s:%u: ", file
, line
);
130 fprintf (stderr
, "%s: ", file
);
134 /* Send to stderr a string as information, with location data passed in.
135 Note that for now this is not intended for general use. */
138 as_info_where (const char *file
, unsigned int line
, unsigned int indent
,
139 const char *format
, ...)
144 va_start (args
, format
);
145 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
147 fprintf (stderr
, "%s:%u: %*s%s%s\n",
148 file
, line
, (int)indent
, "", _("Info: "), buffer
);
151 /* Send to stderr a string as a warning, and locate warning
153 Please only use this for when we have some recovery action.
154 Please explain in string (which may have '\n's) what recovery was
158 as_tsktsk (const char *format
, ...)
163 va_start (args
, format
);
164 vfprintf (stderr
, format
, args
);
166 (void) putc ('\n', stderr
);
167 as_report_context ();
170 /* The common portion of as_warn and as_warn_where. */
173 as_warn_internal (const char *file
, unsigned int line
, char *buffer
)
175 bool context
= false;
181 file
= as_where_top (&line
);
189 fprintf (stderr
, "%s:%u: %s%s\n", file
, line
, _("Warning: "), buffer
);
191 fprintf (stderr
, "%s: %s%s\n", file
, _("Warning: "), buffer
);
194 fprintf (stderr
, "%s%s\n", _("Warning: "), buffer
);
197 as_report_context ();
200 listing_warning (buffer
);
204 /* Send to stderr a string as a warning, and locate warning
206 Please only use this for when we have some recovery action.
207 Please explain in string (which may have '\n's) what recovery was
211 as_warn (const char *format
, ...)
216 if (!flag_no_warnings
)
218 va_start (args
, format
);
219 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
221 as_warn_internal ((char *) NULL
, 0, buffer
);
225 /* Like as_warn but the file name and line number are passed in.
226 Unfortunately, we have to repeat the function in order to handle
227 the varargs correctly and portably. */
230 as_warn_where (const char *file
, unsigned int line
, const char *format
, ...)
235 if (!flag_no_warnings
)
237 va_start (args
, format
);
238 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
240 as_warn_internal (file
, line
, buffer
);
244 /* The common portion of as_bad and as_bad_where. */
247 as_bad_internal (const char *file
, unsigned int line
, char *buffer
)
249 bool context
= false;
255 file
= as_where_top (&line
);
263 fprintf (stderr
, "%s:%u: %s%s\n", file
, line
, _("Error: "), buffer
);
265 fprintf (stderr
, "%s: %s%s\n", file
, _("Error: "), buffer
);
268 fprintf (stderr
, "%s%s\n", _("Error: "), buffer
);
271 as_report_context ();
274 listing_error (buffer
);
278 /* Send to stderr a string as a warning, and locate warning in input
279 file(s). Please use when there is no recovery, but we want to
280 continue processing but not produce an object file.
281 Please explain in string (which may have '\n's) what recovery was
285 as_bad (const char *format
, ...)
290 va_start (args
, format
);
291 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
294 as_bad_internal ((char *) NULL
, 0, buffer
);
297 /* Like as_bad but the file name and line number are passed in.
298 Unfortunately, we have to repeat the function in order to handle
299 the varargs correctly and portably. */
302 as_bad_where (const char *file
, unsigned int line
, const char *format
, ...)
307 va_start (args
, format
);
308 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
311 as_bad_internal (file
, line
, buffer
);
314 /* Send to stderr a string as a fatal message, and print location of
315 error in input file(s).
316 Please only use this for when we DON'T have some recovery action.
317 It xexit()s with a warning status. */
320 as_fatal (const char *format
, ...)
325 va_start (args
, format
);
326 fprintf (stderr
, _("Fatal error: "));
327 vfprintf (stderr
, format
, args
);
328 (void) putc ('\n', stderr
);
330 as_report_context ();
331 /* Delete the output file, if it exists. This will prevent make from
332 thinking that a file was created and hence does not need rebuilding. */
333 if (out_file_name
!= NULL
)
334 unlink_if_ordinary (out_file_name
);
335 xexit (EXIT_FAILURE
);
338 /* Indicate internal constency error.
339 Arguments: Filename, line number, optional function name.
340 FILENAME may be NULL, which we use for crash-via-signal. */
343 as_abort (const char *file
, int line
, const char *fn
)
348 fprintf (stderr
, _("Internal error (%s).\n"), fn
? fn
: "unknown");
350 fprintf (stderr
, _("Internal error in %s at %s:%d.\n"), fn
, file
, line
);
352 fprintf (stderr
, _("Internal error at %s:%d.\n"), file
, line
);
353 as_report_context ();
355 fprintf (stderr
, _("Please report this bug.\n"));
357 xexit (EXIT_FAILURE
);
360 /* Handler for fatal signals, such as SIGSEGV. */
363 signal_crash (int signo
)
365 /* Reset, to prevent unbounded recursion. */
366 signal (signo
, SIG_DFL
);
368 as_abort (NULL
, 0, strsignal (signo
));
371 /* Register signal handlers, for less abrubt crashes. */
377 signal (SIGSEGV
, signal_crash
);
380 signal (SIGILL
, signal_crash
);
383 signal (SIGBUS
, signal_crash
);
386 signal (SIGABRT
, signal_crash
);
388 #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
389 signal (SIGIOT
, signal_crash
);
392 signal (SIGFPE
, signal_crash
);
396 /* Support routines. */
398 #define HEX_MAX_THRESHOLD 1024
399 #define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD)
402 as_internal_value_out_of_range (const char *prefix
,
415 if (val
>= min
&& val
<= max
)
417 addressT right
= max
& -max
;
422 /* xgettext:c-format */
423 err
= _("%s out of domain (%" PRId64
424 " is not a multiple of %" PRId64
")");
427 as_bad_where (file
, line
, err
, prefix
, (int64_t) val
, (int64_t) right
);
429 as_warn_where (file
, line
, err
, prefix
, (int64_t) val
, (int64_t) right
);
431 else if ( val
< HEX_MAX_THRESHOLD
432 && min
< HEX_MAX_THRESHOLD
433 && max
< HEX_MAX_THRESHOLD
434 && val
> HEX_MIN_THRESHOLD
435 && min
> HEX_MIN_THRESHOLD
436 && max
> HEX_MIN_THRESHOLD
)
438 /* xgettext:c-format. */
439 err
= _("%s out of range (%" PRId64
440 " is not between %" PRId64
" and %" PRId64
")");
443 as_bad_where (file
, line
, err
, prefix
,
444 (int64_t) val
, (int64_t) min
, (int64_t) max
);
446 as_warn_where (file
, line
, err
, prefix
,
447 (int64_t) val
, (int64_t) min
, (int64_t) max
);
451 /* xgettext:c-format. */
452 err
= _("%s out of range (0x%" PRIx64
453 " is not between 0x%" PRIx64
" and 0x%" PRIx64
")");
456 as_bad_where (file
, line
, err
, prefix
,
457 (int64_t) val
, (int64_t) min
, (int64_t) max
);
459 as_warn_where (file
, line
, err
, prefix
,
460 (int64_t) val
, (int64_t) min
, (int64_t) max
);
465 as_warn_value_out_of_range (const char *prefix
,
472 as_internal_value_out_of_range (prefix
, value
, min
, max
, file
, line
, false);
476 as_bad_value_out_of_range (const char *prefix
,
483 as_internal_value_out_of_range (prefix
, value
, min
, max
, file
, line
, true);