1 /* messages.c - error reporter -
2 Copyright (C) 1987-2014 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
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
identify(char * file)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
had_warnings(void)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
had_errors(void)98 had_errors (void)
99 {
100 return error_count;
101 }
102
103 /* Print the current location to stderr. */
104
105 static void
as_show_where(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
as_tsktsk(const char * format,...)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
as_warn_internal(char * file,unsigned int line,char * buffer)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)
154 fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Warning: "), buffer);
155 else
156 fprintf (stderr, "%s: %s%s\n", file, _("Warning: "), buffer);
157 }
158 else
159 fprintf (stderr, "%s%s\n", _("Warning: "), buffer);
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
as_warn(const char * format,...)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
as_warn_where(char * file,unsigned int line,const char * format,...)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
as_bad_internal(char * file,unsigned int line,char * buffer)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)
219 fprintf (stderr, "%s:%u: %s%s\n", file, line, _("Error: "), buffer);
220 else
221 fprintf (stderr, "%s: %s%s\n", file, _("Error: "), buffer);
222 }
223 else
224 fprintf (stderr, "%s%s\n", _("Error: "), buffer);
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
as_bad(const char * format,...)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
as_bad_where(char * file,unsigned int line,const char * format,...)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
as_fatal(const char * format,...)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
as_assert(const char * file,int line,const char * fn)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)
298 fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"),
299 fn, file, line);
300 else
301 fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line);
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
as_abort(const char * file,int line,const char * fn)310 as_abort (const char *file, int line, const char *fn)
311 {
312 as_show_where ();
313 if (fn)
314 fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"),
315 file, line, fn);
316 else
317 fprintf (stderr, _("Internal error, aborting at %s line %d\n"),
318 file, line);
319 fprintf (stderr, _("Please report this bug.\n"));
320 xexit (EXIT_FAILURE);
321 }
322
323 /* Support routines. */
324
325 void
sprint_value(char * buf,valueT val)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
as_internal_value_out_of_range(char * prefix,offsetT val,offsetT min,offsetT max,char * file,unsigned line,int bad)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
as_warn_value_out_of_range(char * prefix,offsetT value,offsetT min,offsetT max,char * file,unsigned line)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
as_bad_value_out_of_range(char * prefix,offsetT value,offsetT min,offsetT max,char * file,unsigned line)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 }
437