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