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 gas_assert (file
!= NULL
&& line
> 0 && indent
<= INT_MAX
);
146 va_start (args
, format
);
147 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
149 fprintf (stderr
, "%s:%u: %*s%s%s\n",
150 file
, line
, (int)indent
, "", _("Info: "), buffer
);
153 /* Send to stderr a string as a warning, and locate warning
155 Please only use this for when we have some recovery action.
156 Please explain in string (which may have '\n's) what recovery was
160 as_tsktsk (const char *format
, ...)
165 va_start (args
, format
);
166 vfprintf (stderr
, format
, args
);
168 (void) putc ('\n', stderr
);
169 as_report_context ();
172 /* The common portion of as_warn and as_warn_where. */
175 as_warn_internal (const char *file
, unsigned int line
, char *buffer
)
177 bool context
= false;
183 file
= as_where_top (&line
);
191 fprintf (stderr
, "%s:%u: %s%s\n", file
, line
, _("Warning: "), buffer
);
193 fprintf (stderr
, "%s: %s%s\n", file
, _("Warning: "), buffer
);
196 fprintf (stderr
, "%s%s\n", _("Warning: "), buffer
);
199 as_report_context ();
202 listing_warning (buffer
);
206 /* Send to stderr a string as a warning, and locate warning
208 Please only use this for when we have some recovery action.
209 Please explain in string (which may have '\n's) what recovery was
213 as_warn (const char *format
, ...)
218 if (!flag_no_warnings
)
220 va_start (args
, format
);
221 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
223 as_warn_internal ((char *) NULL
, 0, buffer
);
227 /* Like as_warn but the file name and line number are passed in.
228 Unfortunately, we have to repeat the function in order to handle
229 the varargs correctly and portably. */
232 as_warn_where (const char *file
, unsigned int line
, const char *format
, ...)
237 if (!flag_no_warnings
)
239 va_start (args
, format
);
240 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
242 as_warn_internal (file
, line
, buffer
);
246 /* The common portion of as_bad and as_bad_where. */
249 as_bad_internal (const char *file
, unsigned int line
, char *buffer
)
251 bool context
= false;
257 file
= as_where_top (&line
);
265 fprintf (stderr
, "%s:%u: %s%s\n", file
, line
, _("Error: "), buffer
);
267 fprintf (stderr
, "%s: %s%s\n", file
, _("Error: "), buffer
);
270 fprintf (stderr
, "%s%s\n", _("Error: "), buffer
);
273 as_report_context ();
276 listing_error (buffer
);
280 /* Send to stderr a string as a warning, and locate warning in input
281 file(s). Please use when there is no recovery, but we want to
282 continue processing but not produce an object file.
283 Please explain in string (which may have '\n's) what recovery was
287 as_bad (const char *format
, ...)
292 va_start (args
, format
);
293 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
296 as_bad_internal ((char *) NULL
, 0, buffer
);
299 /* Like as_bad but the file name and line number are passed in.
300 Unfortunately, we have to repeat the function in order to handle
301 the varargs correctly and portably. */
304 as_bad_where (const char *file
, unsigned int line
, const char *format
, ...)
309 va_start (args
, format
);
310 vsnprintf (buffer
, sizeof (buffer
), format
, args
);
313 as_bad_internal (file
, line
, buffer
);
316 /* Send to stderr a string as a fatal message, and print location of
317 error in input file(s).
318 Please only use this for when we DON'T have some recovery action.
319 It xexit()s with a warning status. */
322 as_fatal (const char *format
, ...)
327 va_start (args
, format
);
328 fprintf (stderr
, _("Fatal error: "));
329 vfprintf (stderr
, format
, args
);
330 (void) putc ('\n', stderr
);
332 as_report_context ();
333 /* Delete the output file, if it exists. This will prevent make from
334 thinking that a file was created and hence does not need rebuilding. */
335 if (out_file_name
!= NULL
)
336 unlink_if_ordinary (out_file_name
);
337 xexit (EXIT_FAILURE
);
340 /* Indicate internal constency error.
341 Arguments: Filename, line number, optional function name.
342 FILENAME may be NULL, which we use for crash-via-signal. */
345 as_abort (const char *file
, int line
, const char *fn
)
350 fprintf (stderr
, _("Internal error (%s).\n"), fn
? fn
: "unknown");
352 fprintf (stderr
, _("Internal error in %s at %s:%d.\n"), fn
, file
, line
);
354 fprintf (stderr
, _("Internal error at %s:%d.\n"), file
, line
);
355 as_report_context ();
357 fprintf (stderr
, _("Please report this bug.\n"));
359 xexit (EXIT_FAILURE
);
362 /* Handler for fatal signals, such as SIGSEGV. */
365 signal_crash (int signo
)
367 /* Reset, to prevent unbounded recursion. */
368 signal (signo
, SIG_DFL
);
370 as_abort (NULL
, 0, strsignal (signo
));
373 /* Register signal handlers, for less abrubt crashes. */
379 signal (SIGSEGV
, signal_crash
);
382 signal (SIGILL
, signal_crash
);
385 signal (SIGBUS
, signal_crash
);
388 signal (SIGABRT
, signal_crash
);
390 #if defined SIGIOT && (!defined SIGABRT || SIGABRT != SIGIOT)
391 signal (SIGIOT
, signal_crash
);
394 signal (SIGFPE
, signal_crash
);
398 /* Support routines. */
400 #define HEX_MAX_THRESHOLD 1024
401 #define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD)
404 as_internal_value_out_of_range (const char *prefix
,
417 if (val
>= min
&& val
<= max
)
419 addressT right
= max
& -max
;
424 /* xgettext:c-format */
425 err
= _("%s out of domain (%" PRId64
426 " is not a multiple of %" PRId64
")");
429 as_bad_where (file
, line
, err
, prefix
, (int64_t) val
, (int64_t) right
);
431 as_warn_where (file
, line
, err
, prefix
, (int64_t) val
, (int64_t) right
);
433 else if ( val
< HEX_MAX_THRESHOLD
434 && min
< HEX_MAX_THRESHOLD
435 && max
< HEX_MAX_THRESHOLD
436 && val
> HEX_MIN_THRESHOLD
437 && min
> HEX_MIN_THRESHOLD
438 && max
> HEX_MIN_THRESHOLD
)
440 /* xgettext:c-format. */
441 err
= _("%s out of range (%" PRId64
442 " is not between %" PRId64
" and %" PRId64
")");
445 as_bad_where (file
, line
, err
, prefix
,
446 (int64_t) val
, (int64_t) min
, (int64_t) max
);
448 as_warn_where (file
, line
, err
, prefix
,
449 (int64_t) val
, (int64_t) min
, (int64_t) max
);
453 /* xgettext:c-format. */
454 err
= _("%s out of range (0x%" PRIx64
455 " is not between 0x%" PRIx64
" and 0x%" PRIx64
")");
458 as_bad_where (file
, line
, err
, prefix
,
459 (int64_t) val
, (int64_t) min
, (int64_t) max
);
461 as_warn_where (file
, line
, err
, prefix
,
462 (int64_t) val
, (int64_t) min
, (int64_t) max
);
467 as_warn_value_out_of_range (const char *prefix
,
474 as_internal_value_out_of_range (prefix
, value
, min
, max
, file
, line
, false);
478 as_bad_value_out_of_range (const char *prefix
,
485 as_internal_value_out_of_range (prefix
, value
, min
, max
, file
, line
, true);