133965Sjdp/* messages.c - error reporter - 2218822Sdim Copyright 1987, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 2000, 2001, 3218822Sdim 2003, 2004, 2005, 2006, 2007 433965Sjdp Free Software Foundation, Inc. 533965Sjdp This file is part of GAS, the GNU Assembler. 633965Sjdp 733965Sjdp GAS is free software; you can redistribute it and/or modify 833965Sjdp it under the terms of the GNU General Public License as published by 933965Sjdp the Free Software Foundation; either version 2, or (at your option) 1033965Sjdp any later version. 1133965Sjdp 1233965Sjdp GAS is distributed in the hope that it will be useful, 1333965Sjdp but WITHOUT ANY WARRANTY; without even the implied warranty of 1433965Sjdp MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 1533965Sjdp GNU General Public License for more details. 1633965Sjdp 1733965Sjdp You should have received a copy of the GNU General Public License 1833965Sjdp along with GAS; see the file COPYING. If not, write to the Free 19218822Sdim Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20218822Sdim 02110-1301, USA. */ 2133965Sjdp 2233965Sjdp#include "as.h" 2333965Sjdp 24130561Sobrienstatic void identify (char *); 25130561Sobrienstatic void as_show_where (void); 26130561Sobrienstatic void as_warn_internal (char *, unsigned int, char *); 27130561Sobrienstatic void as_bad_internal (char *, unsigned int, char *); 2833965Sjdp 2977298Sobrien/* Despite the rest of the comments in this file, (FIXME-SOON), 30130561Sobrien here is the current scheme for error messages etc: 3133965Sjdp 32130561Sobrien as_fatal() is used when gas is quite confused and 33130561Sobrien continuing the assembly is pointless. In this case we 34130561Sobrien exit immediately with error status. 35130561Sobrien 36130561Sobrien as_bad() is used to mark errors that result in what we 37130561Sobrien presume to be a useless object file. Say, we ignored 38130561Sobrien something that might have been vital. If we see any of 39130561Sobrien these, assembly will continue to the end of the source, 40130561Sobrien no object file will be produced, and we will terminate 41130561Sobrien with error status. The new option, -Z, tells us to 42130561Sobrien produce an object file anyway but we still exit with 43130561Sobrien error status. The assumption here is that you don't want 44130561Sobrien this object file but we could be wrong. 45130561Sobrien 46130561Sobrien as_warn() is used when we have an error from which we 47130561Sobrien have a plausible error recovery. eg, masking the top 48130561Sobrien bits of a constant that is longer than will fit in the 49130561Sobrien destination. In this case we will continue to assemble 50130561Sobrien the source, although we may have made a bad assumption, 51130561Sobrien and we will produce an object file and return normal exit 52130561Sobrien status (ie, no error). The new option -X tells us to 53130561Sobrien treat all as_warn() errors as as_bad() errors. That is, 54130561Sobrien no object file will be produced and we will exit with 55130561Sobrien error status. The idea here is that we don't kill an 56130561Sobrien entire make because of an error that we knew how to 57130561Sobrien correct. On the other hand, sometimes you might want to 58130561Sobrien stop the make at these points. 59130561Sobrien 60130561Sobrien as_tsktsk() is used when we see a minor error for which 61130561Sobrien our error recovery action is almost certainly correct. 62130561Sobrien In this case, we print a message and then assembly 63130561Sobrien continues as though no error occurred. */ 64130561Sobrien 6533965Sjdpstatic void 66130561Sobrienidentify (char *file) 6733965Sjdp{ 6833965Sjdp static int identified; 69130561Sobrien 7033965Sjdp if (identified) 7133965Sjdp return; 7233965Sjdp identified++; 7333965Sjdp 7433965Sjdp if (!file) 7533965Sjdp { 7633965Sjdp unsigned int x; 7733965Sjdp as_where (&file, &x); 7833965Sjdp } 7933965Sjdp 8033965Sjdp if (file) 8133965Sjdp fprintf (stderr, "%s: ", file); 8260484Sobrien fprintf (stderr, _("Assembler messages:\n")); 8333965Sjdp} 8433965Sjdp 8577298Sobrien/* The number of warnings issued. */ 8677298Sobrienstatic int warning_count; 8733965Sjdp 8877298Sobrienint 89130561Sobrienhad_warnings (void) 9033965Sjdp{ 91130561Sobrien return warning_count; 9233965Sjdp} 9333965Sjdp 9433965Sjdp/* Nonzero if we've hit a 'bad error', and should not write an obj file, 9577298Sobrien and exit with a nonzero error code. */ 9633965Sjdp 9733965Sjdpstatic int error_count; 9833965Sjdp 9977298Sobrienint 100130561Sobrienhad_errors (void) 10133965Sjdp{ 102130561Sobrien return error_count; 10333965Sjdp} 10433965Sjdp 10533965Sjdp/* Print the current location to stderr. */ 10633965Sjdp 10733965Sjdpstatic void 108130561Sobrienas_show_where (void) 10933965Sjdp{ 11033965Sjdp char *file; 11133965Sjdp unsigned int line; 11233965Sjdp 11333965Sjdp as_where (&file, &line); 11433965Sjdp identify (file); 11533965Sjdp if (file) 11633965Sjdp fprintf (stderr, "%s:%u: ", file, line); 11733965Sjdp} 11833965Sjdp 11977298Sobrien/* Send to stderr a string as a warning, and locate warning 12077298Sobrien in input file(s). 12177298Sobrien Please only use this for when we have some recovery action. 12277298Sobrien Please explain in string (which may have '\n's) what recovery was 12377298Sobrien done. */ 12433965Sjdp 12533965Sjdp#ifdef USE_STDARG 12677298Sobrienvoid 12777298Sobrienas_tsktsk (const char *format, ...) 12833965Sjdp{ 12933965Sjdp va_list args; 13033965Sjdp 13133965Sjdp as_show_where (); 13233965Sjdp va_start (args, format); 13333965Sjdp vfprintf (stderr, format, args); 13433965Sjdp va_end (args); 13533965Sjdp (void) putc ('\n', stderr); 13677298Sobrien} 13733965Sjdp#else 13877298Sobrienvoid 13933965Sjdpas_tsktsk (format, va_alist) 14033965Sjdp const char *format; 14133965Sjdp va_dcl 14233965Sjdp{ 14333965Sjdp va_list args; 14433965Sjdp 14533965Sjdp as_show_where (); 14633965Sjdp va_start (args); 14733965Sjdp vfprintf (stderr, format, args); 14833965Sjdp va_end (args); 14933965Sjdp (void) putc ('\n', stderr); 15077298Sobrien} 15133965Sjdp#endif /* not NO_STDARG */ 15233965Sjdp 15333965Sjdp/* The common portion of as_warn and as_warn_where. */ 15433965Sjdp 15533965Sjdpstatic void 156130561Sobrienas_warn_internal (char *file, unsigned int line, char *buffer) 15733965Sjdp{ 15833965Sjdp ++warning_count; 15933965Sjdp 16033965Sjdp if (file == NULL) 16133965Sjdp as_where (&file, &line); 16233965Sjdp 16333965Sjdp identify (file); 16433965Sjdp if (file) 16533965Sjdp fprintf (stderr, "%s:%u: ", file, line); 16660484Sobrien fprintf (stderr, _("Warning: ")); 16733965Sjdp fputs (buffer, stderr); 16833965Sjdp (void) putc ('\n', stderr); 16933965Sjdp#ifndef NO_LISTING 17033965Sjdp listing_warning (buffer); 17133965Sjdp#endif 17233965Sjdp} 17333965Sjdp 17477298Sobrien/* Send to stderr a string as a warning, and locate warning 17577298Sobrien in input file(s). 17677298Sobrien Please only use this for when we have some recovery action. 17777298Sobrien Please explain in string (which may have '\n's) what recovery was 17877298Sobrien done. */ 17933965Sjdp 18033965Sjdp#ifdef USE_STDARG 18177298Sobrienvoid 18277298Sobrienas_warn (const char *format, ...) 18333965Sjdp{ 18433965Sjdp va_list args; 18538889Sjdp char buffer[2000]; 18633965Sjdp 18733965Sjdp if (!flag_no_warnings) 18833965Sjdp { 18933965Sjdp va_start (args, format); 190218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 19133965Sjdp va_end (args); 19233965Sjdp as_warn_internal ((char *) NULL, 0, buffer); 19333965Sjdp } 19477298Sobrien} 19533965Sjdp#else 19677298Sobrienvoid 19733965Sjdpas_warn (format, va_alist) 19833965Sjdp const char *format; 19933965Sjdp va_dcl 20033965Sjdp{ 20133965Sjdp va_list args; 20238889Sjdp char buffer[2000]; 20333965Sjdp 20433965Sjdp if (!flag_no_warnings) 20533965Sjdp { 20633965Sjdp va_start (args); 207218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 20833965Sjdp va_end (args); 20933965Sjdp as_warn_internal ((char *) NULL, 0, buffer); 21033965Sjdp } 21177298Sobrien} 21233965Sjdp#endif /* not NO_STDARG */ 21333965Sjdp 21477298Sobrien/* Like as_bad but the file name and line number are passed in. 21577298Sobrien Unfortunately, we have to repeat the function in order to handle 21677298Sobrien the varargs correctly and portably. */ 21733965Sjdp 21833965Sjdp#ifdef USE_STDARG 21977298Sobrienvoid 22077298Sobrienas_warn_where (char *file, unsigned int line, const char *format, ...) 22133965Sjdp{ 22233965Sjdp va_list args; 22338889Sjdp char buffer[2000]; 22433965Sjdp 22533965Sjdp if (!flag_no_warnings) 22633965Sjdp { 22733965Sjdp va_start (args, format); 228218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 22933965Sjdp va_end (args); 23033965Sjdp as_warn_internal (file, line, buffer); 23133965Sjdp } 23277298Sobrien} 23333965Sjdp#else 23477298Sobrienvoid 23533965Sjdpas_warn_where (file, line, format, va_alist) 23633965Sjdp char *file; 23733965Sjdp unsigned int line; 23833965Sjdp const char *format; 23933965Sjdp va_dcl 24033965Sjdp{ 24133965Sjdp va_list args; 24238889Sjdp char buffer[2000]; 24333965Sjdp 24433965Sjdp if (!flag_no_warnings) 24533965Sjdp { 24633965Sjdp va_start (args); 247218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 24833965Sjdp va_end (args); 24933965Sjdp as_warn_internal (file, line, buffer); 25033965Sjdp } 25177298Sobrien} 25233965Sjdp#endif /* not NO_STDARG */ 25333965Sjdp 25433965Sjdp/* The common portion of as_bad and as_bad_where. */ 25533965Sjdp 25633965Sjdpstatic void 257130561Sobrienas_bad_internal (char *file, unsigned int line, char *buffer) 25833965Sjdp{ 25933965Sjdp ++error_count; 26033965Sjdp 26133965Sjdp if (file == NULL) 26233965Sjdp as_where (&file, &line); 26333965Sjdp 26433965Sjdp identify (file); 26533965Sjdp if (file) 26633965Sjdp fprintf (stderr, "%s:%u: ", file, line); 26760484Sobrien fprintf (stderr, _("Error: ")); 26833965Sjdp fputs (buffer, stderr); 26933965Sjdp (void) putc ('\n', stderr); 27033965Sjdp#ifndef NO_LISTING 27133965Sjdp listing_error (buffer); 27233965Sjdp#endif 27333965Sjdp} 27433965Sjdp 27577298Sobrien/* Send to stderr a string as a warning, and locate warning in input 27677298Sobrien file(s). Please us when there is no recovery, but we want to 27777298Sobrien continue processing but not produce an object file. 27877298Sobrien Please explain in string (which may have '\n's) what recovery was 27977298Sobrien done. */ 28033965Sjdp 28133965Sjdp#ifdef USE_STDARG 28277298Sobrienvoid 28377298Sobrienas_bad (const char *format, ...) 28433965Sjdp{ 28533965Sjdp va_list args; 28638889Sjdp char buffer[2000]; 28733965Sjdp 28833965Sjdp va_start (args, format); 289218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 29033965Sjdp va_end (args); 29133965Sjdp 29233965Sjdp as_bad_internal ((char *) NULL, 0, buffer); 29333965Sjdp} 29433965Sjdp 29533965Sjdp#else 29677298Sobrienvoid 29733965Sjdpas_bad (format, va_alist) 29833965Sjdp const char *format; 29933965Sjdp va_dcl 30033965Sjdp{ 30133965Sjdp va_list args; 30238889Sjdp char buffer[2000]; 30333965Sjdp 30433965Sjdp va_start (args); 305218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 30633965Sjdp va_end (args); 30733965Sjdp 30833965Sjdp as_bad_internal ((char *) NULL, 0, buffer); 30933965Sjdp} 31033965Sjdp#endif /* not NO_STDARG */ 31133965Sjdp 31277298Sobrien/* Like as_bad but the file name and line number are passed in. 31377298Sobrien Unfortunately, we have to repeat the function in order to handle 31477298Sobrien the varargs correctly and portably. */ 31533965Sjdp 31633965Sjdp#ifdef USE_STDARG 31777298Sobrienvoid 31877298Sobrienas_bad_where (char *file, unsigned int line, const char *format, ...) 31933965Sjdp{ 32033965Sjdp va_list args; 32138889Sjdp char buffer[2000]; 32233965Sjdp 32333965Sjdp va_start (args, format); 324218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 32533965Sjdp va_end (args); 32633965Sjdp 32733965Sjdp as_bad_internal (file, line, buffer); 32833965Sjdp} 32933965Sjdp 33033965Sjdp#else 33177298Sobrienvoid 33233965Sjdpas_bad_where (file, line, format, va_alist) 33333965Sjdp char *file; 33433965Sjdp unsigned int line; 33533965Sjdp const char *format; 33633965Sjdp va_dcl 33733965Sjdp{ 33833965Sjdp va_list args; 33938889Sjdp char buffer[2000]; 34033965Sjdp 34133965Sjdp va_start (args); 342218822Sdim vsnprintf (buffer, sizeof (buffer), format, args); 34333965Sjdp va_end (args); 34433965Sjdp 34533965Sjdp as_bad_internal (file, line, buffer); 34633965Sjdp} 34733965Sjdp#endif /* not NO_STDARG */ 34833965Sjdp 34977298Sobrien/* Send to stderr a string as a fatal message, and print location of 35077298Sobrien error in input file(s). 35177298Sobrien Please only use this for when we DON'T have some recovery action. 35277298Sobrien It xexit()s with a warning status. */ 35333965Sjdp 35433965Sjdp#ifdef USE_STDARG 35577298Sobrienvoid 35677298Sobrienas_fatal (const char *format, ...) 35733965Sjdp{ 35833965Sjdp va_list args; 35933965Sjdp 36033965Sjdp as_show_where (); 36133965Sjdp va_start (args, format); 36260484Sobrien fprintf (stderr, _("Fatal error: ")); 36333965Sjdp vfprintf (stderr, format, args); 36433965Sjdp (void) putc ('\n', stderr); 36533965Sjdp va_end (args); 36677298Sobrien /* Delete the output file, if it exists. This will prevent make from 36777298Sobrien thinking that a file was created and hence does not need rebuilding. */ 36877298Sobrien if (out_file_name != NULL) 369218822Sdim unlink_if_ordinary (out_file_name); 37033965Sjdp xexit (EXIT_FAILURE); 37177298Sobrien} 37233965Sjdp#else 37377298Sobrienvoid 37433965Sjdpas_fatal (format, va_alist) 37533965Sjdp char *format; 37633965Sjdp va_dcl 37733965Sjdp{ 37833965Sjdp va_list args; 37933965Sjdp 38033965Sjdp as_show_where (); 38133965Sjdp va_start (args); 38260484Sobrien fprintf (stderr, _("Fatal error: ")); 38333965Sjdp vfprintf (stderr, format, args); 38433965Sjdp (void) putc ('\n', stderr); 38533965Sjdp va_end (args); 38633965Sjdp xexit (EXIT_FAILURE); 38777298Sobrien} 38833965Sjdp#endif /* not NO_STDARG */ 38933965Sjdp 39077298Sobrien/* Indicate assertion failure. 39177298Sobrien Arguments: Filename, line number, optional function name. */ 39233965Sjdp 39333965Sjdpvoid 394130561Sobrienas_assert (const char *file, int line, const char *fn) 39533965Sjdp{ 39633965Sjdp as_show_where (); 39760484Sobrien fprintf (stderr, _("Internal error!\n")); 39833965Sjdp if (fn) 39960484Sobrien fprintf (stderr, _("Assertion failure in %s at %s line %d.\n"), 40060484Sobrien fn, file, line); 40160484Sobrien else 40260484Sobrien fprintf (stderr, _("Assertion failure at %s line %d.\n"), file, line); 40360484Sobrien fprintf (stderr, _("Please report this bug.\n")); 40433965Sjdp xexit (EXIT_FAILURE); 40533965Sjdp} 40633965Sjdp 40733965Sjdp/* as_abort: Print a friendly message saying how totally hosed we are, 40833965Sjdp and exit without producing a core file. */ 40977298Sobrien 41033965Sjdpvoid 411130561Sobrienas_abort (const char *file, int line, const char *fn) 41233965Sjdp{ 41333965Sjdp as_show_where (); 41433965Sjdp if (fn) 41560484Sobrien fprintf (stderr, _("Internal error, aborting at %s line %d in %s\n"), 41660484Sobrien file, line, fn); 41760484Sobrien else 41860484Sobrien fprintf (stderr, _("Internal error, aborting at %s line %d\n"), 41960484Sobrien file, line); 42060484Sobrien fprintf (stderr, _("Please report this bug.\n")); 42133965Sjdp xexit (EXIT_FAILURE); 42233965Sjdp} 42333965Sjdp 42433965Sjdp/* Support routines. */ 42533965Sjdp 42633965Sjdpvoid 427218822Sdimsprint_value (char *buf, valueT val) 42833965Sjdp{ 42933965Sjdp if (sizeof (val) <= sizeof (long)) 43033965Sjdp { 431218822Sdim sprintf (buf, "%ld", (long) val); 43233965Sjdp return; 43333965Sjdp } 43433965Sjdp if (sizeof (val) <= sizeof (bfd_vma)) 43533965Sjdp { 436218822Sdim sprintf_vma (buf, val); 43733965Sjdp return; 43833965Sjdp } 43933965Sjdp abort (); 44033965Sjdp} 44133965Sjdp 442218822Sdim#define HEX_MAX_THRESHOLD 1024 443218822Sdim#define HEX_MIN_THRESHOLD -(HEX_MAX_THRESHOLD) 444218822Sdim 445218822Sdimstatic void 446218822Sdimas_internal_value_out_of_range (char * prefix, 447218822Sdim offsetT val, 448218822Sdim offsetT min, 449218822Sdim offsetT max, 450218822Sdim char * file, 451218822Sdim unsigned line, 452218822Sdim int bad) 45333965Sjdp{ 454218822Sdim const char * err; 455218822Sdim 456218822Sdim if (prefix == NULL) 457218822Sdim prefix = ""; 458218822Sdim 459218822Sdim if (val >= min && val <= max) 46033965Sjdp { 461218822Sdim addressT right = max & -max; 462218822Sdim 463218822Sdim if (max <= 1) 464218822Sdim abort (); 465218822Sdim 466218822Sdim /* xgettext:c-format */ 467218822Sdim err = _("%s out of domain (%d is not a multiple of %d)"); 468218822Sdim if (bad) 469218822Sdim as_bad_where (file, line, err, 470218822Sdim prefix, (int) val, (int) right); 471218822Sdim else 472218822Sdim as_warn_where (file, line, err, 473218822Sdim prefix, (int) val, (int) right); 47433965Sjdp return; 47533965Sjdp } 476218822Sdim 477218822Sdim if ( val < HEX_MAX_THRESHOLD 478218822Sdim && min < HEX_MAX_THRESHOLD 479218822Sdim && max < HEX_MAX_THRESHOLD 480218822Sdim && val > HEX_MIN_THRESHOLD 481218822Sdim && min > HEX_MIN_THRESHOLD 482218822Sdim && max > HEX_MIN_THRESHOLD) 48333965Sjdp { 484218822Sdim /* xgettext:c-format */ 485218822Sdim err = _("%s out of range (%d is not between %d and %d)"); 486218822Sdim 487218822Sdim if (bad) 488218822Sdim as_bad_where (file, line, err, 489218822Sdim prefix, (int) val, (int) min, (int) max); 490218822Sdim else 491218822Sdim as_warn_where (file, line, err, 492218822Sdim prefix, (int) val, (int) min, (int) max); 49333965Sjdp } 494218822Sdim else 495218822Sdim { 496218822Sdim char val_buf [sizeof (val) * 3 + 2]; 497218822Sdim char min_buf [sizeof (val) * 3 + 2]; 498218822Sdim char max_buf [sizeof (val) * 3 + 2]; 499218822Sdim 500218822Sdim if (sizeof (val) > sizeof (bfd_vma)) 501218822Sdim abort (); 502218822Sdim 503218822Sdim sprintf_vma (val_buf, val); 504218822Sdim sprintf_vma (min_buf, min); 505218822Sdim sprintf_vma (max_buf, max); 506218822Sdim 507218822Sdim /* xgettext:c-format. */ 508218822Sdim err = _("%s out of range (0x%s is not between 0x%s and 0x%s)"); 509218822Sdim 510218822Sdim if (bad) 511218822Sdim as_bad_where (file, line, err, prefix, val_buf, min_buf, max_buf); 512218822Sdim else 513218822Sdim as_warn_where (file, line, err, prefix, val_buf, min_buf, max_buf); 514218822Sdim } 51533965Sjdp} 516218822Sdim 517218822Sdimvoid 518218822Sdimas_warn_value_out_of_range (char * prefix, 519218822Sdim offsetT value, 520218822Sdim offsetT min, 521218822Sdim offsetT max, 522218822Sdim char * file, 523218822Sdim unsigned line) 524218822Sdim{ 525218822Sdim as_internal_value_out_of_range (prefix, value, min, max, file, line, 0); 526218822Sdim} 527218822Sdim 528218822Sdimvoid 529218822Sdimas_bad_value_out_of_range (char * prefix, 530218822Sdim offsetT value, 531218822Sdim offsetT min, 532218822Sdim offsetT max, 533218822Sdim char * file, 534218822Sdim unsigned line) 535218822Sdim{ 536218822Sdim as_internal_value_out_of_range (prefix, value, min, max, file, line, 1); 537218822Sdim} 538