1 /* messages.c - error reporter - 2 Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001 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 PARAMS ((char *)); 46 static void as_show_where PARAMS ((void)); 47 static void as_warn_internal PARAMS ((char *, unsigned int, char *)); 48 static void as_bad_internal PARAMS ((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 87 static void 88 identify (file) 89 char *file; 90 { 91 static int identified; 92 if (identified) 93 return; 94 identified++; 95 96 if (!file) 97 { 98 unsigned int x; 99 as_where (&file, &x); 100 } 101 102 if (file) 103 fprintf (stderr, "%s: ", file); 104 fprintf (stderr, _("Assembler messages:\n")); 105 } 106 107 /* The number of warnings issued. */ 108 static int warning_count; 109 110 int 111 had_warnings () 112 { 113 return (warning_count); 114 } 115 116 /* Nonzero if we've hit a 'bad error', and should not write an obj file, 117 and exit with a nonzero error code. */ 118 119 static int error_count; 120 121 int 122 had_errors () 123 { 124 return (error_count); 125 } 126 127 /* Print the current location to stderr. */ 128 129 static void 130 as_show_where () 131 { 132 char *file; 133 unsigned int line; 134 135 as_where (&file, &line); 136 identify (file); 137 if (file) 138 fprintf (stderr, "%s:%u: ", file, line); 139 } 140 141 /* Like perror(3), but with more info. */ 142 143 void 144 as_perror (gripe, filename) 145 const char *gripe; /* Unpunctuated error theme. */ 146 const char *filename; 147 { 148 const char *errtxt; 149 150 as_show_where (); 151 fprintf (stderr, gripe, filename); 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 (file, line, buffer) 202 char *file; 203 unsigned int line; 204 char *buffer; 205 { 206 ++warning_count; 207 208 if (file == NULL) 209 as_where (&file, &line); 210 211 identify (file); 212 if (file) 213 fprintf (stderr, "%s:%u: ", file, line); 214 fprintf (stderr, _("Warning: ")); 215 fputs (buffer, stderr); 216 (void) putc ('\n', stderr); 217 #ifndef NO_LISTING 218 listing_warning (buffer); 219 #endif 220 } 221 222 /* Send to stderr a string as a warning, and locate warning 223 in input file(s). 224 Please only use this for when we have some recovery action. 225 Please explain in string (which may have '\n's) what recovery was 226 done. */ 227 228 #ifdef USE_STDARG 229 void 230 as_warn (const char *format, ...) 231 { 232 va_list args; 233 char buffer[2000]; 234 235 if (!flag_no_warnings) 236 { 237 va_start (args, format); 238 vsprintf (buffer, format, args); 239 va_end (args); 240 as_warn_internal ((char *) NULL, 0, buffer); 241 } 242 } 243 #else 244 void 245 as_warn (format, va_alist) 246 const char *format; 247 va_dcl 248 { 249 va_list args; 250 char buffer[2000]; 251 252 if (!flag_no_warnings) 253 { 254 va_start (args); 255 vsprintf (buffer, format, args); 256 va_end (args); 257 as_warn_internal ((char *) NULL, 0, buffer); 258 } 259 } 260 #endif /* not NO_STDARG */ 261 262 /* Like as_bad but the file name and line number are passed in. 263 Unfortunately, we have to repeat the function in order to handle 264 the varargs correctly and portably. */ 265 266 #ifdef USE_STDARG 267 void 268 as_warn_where (char *file, unsigned int line, const char *format, ...) 269 { 270 va_list args; 271 char buffer[2000]; 272 273 if (!flag_no_warnings) 274 { 275 va_start (args, format); 276 vsprintf (buffer, format, args); 277 va_end (args); 278 as_warn_internal (file, line, buffer); 279 } 280 } 281 #else 282 void 283 as_warn_where (file, line, format, va_alist) 284 char *file; 285 unsigned int line; 286 const char *format; 287 va_dcl 288 { 289 va_list args; 290 char buffer[2000]; 291 292 if (!flag_no_warnings) 293 { 294 va_start (args); 295 vsprintf (buffer, format, args); 296 va_end (args); 297 as_warn_internal (file, line, buffer); 298 } 299 } 300 #endif /* not NO_STDARG */ 301 302 /* The common portion of as_bad and as_bad_where. */ 303 304 static void 305 as_bad_internal (file, line, buffer) 306 char *file; 307 unsigned int line; 308 char *buffer; 309 { 310 ++error_count; 311 312 if (file == NULL) 313 as_where (&file, &line); 314 315 identify (file); 316 if (file) 317 fprintf (stderr, "%s:%u: ", file, line); 318 fprintf (stderr, _("Error: ")); 319 fputs (buffer, stderr); 320 (void) putc ('\n', stderr); 321 #ifndef NO_LISTING 322 listing_error (buffer); 323 #endif 324 } 325 326 /* Send to stderr a string as a warning, and locate warning in input 327 file(s). Please us when there is no recovery, but we want to 328 continue processing but not produce an object file. 329 Please explain in string (which may have '\n's) what recovery was 330 done. */ 331 332 #ifdef USE_STDARG 333 void 334 as_bad (const char *format, ...) 335 { 336 va_list args; 337 char buffer[2000]; 338 339 va_start (args, format); 340 vsprintf (buffer, format, args); 341 va_end (args); 342 343 as_bad_internal ((char *) NULL, 0, buffer); 344 } 345 346 #else 347 void 348 as_bad (format, va_alist) 349 const char *format; 350 va_dcl 351 { 352 va_list args; 353 char buffer[2000]; 354 355 va_start (args); 356 vsprintf (buffer, format, args); 357 va_end (args); 358 359 as_bad_internal ((char *) NULL, 0, buffer); 360 } 361 #endif /* not NO_STDARG */ 362 363 /* Like as_bad but the file name and line number are passed in. 364 Unfortunately, we have to repeat the function in order to handle 365 the varargs correctly and portably. */ 366 367 #ifdef USE_STDARG 368 void 369 as_bad_where (char *file, unsigned int line, const char *format, ...) 370 { 371 va_list args; 372 char buffer[2000]; 373 374 va_start (args, format); 375 vsprintf (buffer, format, args); 376 va_end (args); 377 378 as_bad_internal (file, line, buffer); 379 } 380 381 #else 382 void 383 as_bad_where (file, line, format, va_alist) 384 char *file; 385 unsigned int line; 386 const char *format; 387 va_dcl 388 { 389 va_list args; 390 char buffer[2000]; 391 392 va_start (args); 393 vsprintf (buffer, format, args); 394 va_end (args); 395 396 as_bad_internal (file, line, buffer); 397 } 398 #endif /* not NO_STDARG */ 399 400 /* Send to stderr a string as a fatal message, and print location of 401 error in input file(s). 402 Please only use this for when we DON'T have some recovery action. 403 It xexit()s with a warning status. */ 404 405 #ifdef USE_STDARG 406 void 407 as_fatal (const char *format, ...) 408 { 409 va_list args; 410 411 as_show_where (); 412 va_start (args, format); 413 fprintf (stderr, _("Fatal error: ")); 414 vfprintf (stderr, format, args); 415 (void) putc ('\n', stderr); 416 va_end (args); 417 /* Delete the output file, if it exists. This will prevent make from 418 thinking that a file was created and hence does not need rebuilding. */ 419 if (out_file_name != NULL) 420 unlink (out_file_name); 421 xexit (EXIT_FAILURE); 422 } 423 #else 424 void 425 as_fatal (format, va_alist) 426 char *format; 427 va_dcl 428 { 429 va_list args; 430 431 as_show_where (); 432 va_start (args); 433 fprintf (stderr, _("Fatal error: ")); 434 vfprintf (stderr, format, args); 435 (void) putc ('\n', stderr); 436 va_end (args); 437 xexit (EXIT_FAILURE); 438 } 439 #endif /* not NO_STDARG */ 440 441 /* Indicate assertion failure. 442 Arguments: Filename, line number, optional function name. */ 443 444 void 445 as_assert (file, line, fn) 446 const char *file, *fn; 447 int line; 448 { 449 as_show_where (); 450 fprintf (stderr, _("Internal error!\n")); 451 if (fn) 452 fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), 453 fn, file, line); 454 else 455 fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); 456 fprintf (stderr, _("Please report this bug.\n")); 457 xexit (EXIT_FAILURE); 458 } 459 460 /* as_abort: Print a friendly message saying how totally hosed we are, 461 and exit without producing a core file. */ 462 463 void 464 as_abort (file, line, fn) 465 const char *file, *fn; 466 int line; 467 { 468 as_show_where (); 469 if (fn) 470 fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), 471 file, line, fn); 472 else 473 fprintf (stderr, _("Internal error, aborting at %s line %d\n"), 474 file, line); 475 fprintf (stderr, _("Please report this bug.\n")); 476 xexit (EXIT_FAILURE); 477 } 478 479 /* Support routines. */ 480 481 void 482 fprint_value (file, val) 483 FILE *file; 484 valueT val; 485 { 486 if (sizeof (val) <= sizeof (long)) 487 { 488 fprintf (file, "%ld", (long) val); 489 return; 490 } 491 #ifdef BFD_ASSEMBLER 492 if (sizeof (val) <= sizeof (bfd_vma)) 493 { 494 fprintf_vma (file, val); 495 return; 496 } 497 #endif 498 abort (); 499 } 500 501 void 502 sprint_value (buf, val) 503 char *buf; 504 valueT val; 505 { 506 if (sizeof (val) <= sizeof (long)) 507 { 508 sprintf (buf, "%ld", (long) val); 509 return; 510 } 511 #ifdef BFD_ASSEMBLER 512 if (sizeof (val) <= sizeof (bfd_vma)) 513 { 514 sprintf_vma (buf, val); 515 return; 516 } 517 #endif 518 abort (); 519 } 520