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