1 /******************************************************************************
3 * Module Name: aslerror - Error handling and statistics
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2013, Intel Corp.
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions, and the following disclaimer,
16 * without modification.
17 * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18 * substantially similar to the "NO WARRANTY" disclaimer below
19 * ("Disclaimer") and any redistribution must be conditioned upon
20 * including a substantially similar Disclaimer requirement for further
21 * binary redistribution.
22 * 3. Neither the names of the above-listed copyright holders nor the names
23 * of any contributors may be used to endorse or promote products derived
24 * from this software without specific prior written permission.
26 * Alternatively, this software may be distributed under the terms of the
27 * GNU General Public License ("GPL") version 2 as published by the Free
28 * Software Foundation.
31 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35 * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41 * POSSIBILITY OF SUCH DAMAGES.
44 #define ASL_EXCEPTIONS
45 #include <contrib/dev/acpica/compiler/aslcompiler.h>
47 #define _COMPONENT ACPI_COMPILER
48 ACPI_MODULE_NAME ("aslerror")
50 /* Local prototypes */
54 ASL_ERROR_MSG *Enode);
57 /*******************************************************************************
59 * FUNCTION: AeClearErrorLog
65 * DESCRIPTION: Empty the error list
67 ******************************************************************************/
73 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
76 /* Walk the error node list */
89 /*******************************************************************************
91 * FUNCTION: AeAddToErrorLog
93 * PARAMETERS: Enode - An error node to add to the log
97 * DESCRIPTION: Add a new error node to the error log. The error log is
98 * ordered by the "logical" line number (cumulative line number
99 * including all include files.)
101 ******************************************************************************/
105 ASL_ERROR_MSG *Enode)
111 /* If Gbl_ErrorLog is null, this is the first error node */
115 Gbl_ErrorLog = Enode;
120 * Walk error list until we find a line number greater than ours.
121 * List is sorted according to line number.
127 (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
133 /* Found our place in the list */
143 Gbl_ErrorLog = Enode;
148 /*******************************************************************************
150 * FUNCTION: AePrintException
152 * PARAMETERS: FileId - ID of output file
153 * Enode - Error node to print
154 * Header - Additional text before each message
158 * DESCRIPTION: Print the contents of an error node.
160 * NOTE: We don't use the FlxxxFile I/O functions here because on error
161 * they abort the compiler and call this function! Since we
162 * are reporting errors here, we ignore most output errors and
163 * just try to get out as much as we can.
165 ******************************************************************************/
170 ASL_ERROR_MSG *Enode,
182 FILE *SourceFile = NULL;
184 BOOLEAN PrematureEOF = FALSE;
194 * Only listing files have a header, and remarks/optimizations
199 /* Ignore remarks if requested */
201 switch (Enode->Level)
205 if (!Gbl_DisplayRemarks)
211 case ASL_OPTIMIZATION:
213 if (!Gbl_DisplayOptimizations)
225 /* Get the file handles */
227 OutputFile = Gbl_Files[FileId].Handle;
230 if (!Enode->SourceLine)
232 /* Use the merged header/source file if present, otherwise use input file */
234 SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
237 SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
242 /* Determine if the error occurred at source file EOF */
244 fseek (SourceFile, 0, SEEK_END);
245 FileSize = ftell (SourceFile);
247 if ((long) Enode->LogicalByteOffset >= FileSize)
256 fprintf (OutputFile, "%s", Header);
259 /* Print filename and line number if present and valid */
263 if (Gbl_VerboseErrors)
265 fprintf (OutputFile, "%-8s", Enode->Filename);
267 if (Enode->LineNumber)
269 if (Enode->SourceLine)
271 fprintf (OutputFile, " %6u: %s",
272 Enode->LineNumber, Enode->SourceLine);
276 fprintf (OutputFile, " %6u: ", Enode->LineNumber);
279 * If not at EOF, get the corresponding source code line and
280 * display it. Don't attempt this if we have a premature EOF
286 * Seek to the offset in the combined source file, read
287 * the source line, and write it to the output.
289 Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
294 "[*** iASL: Seek error on source code temp file %s ***]",
295 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
299 RActual = fread (&SourceByte, 1, 1, SourceFile);
303 "[*** iASL: Read error on source code temp file %s ***]",
304 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
308 /* Read/write the source line, up to the maximum line length */
310 while (RActual && SourceByte && (SourceByte != '\n'))
314 /* After the max line length, we will just read the line, no write */
316 if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
318 printf ("[*** iASL: Write error on output file ***]\n");
322 else if (Total == 256)
325 "\n[*** iASL: Very long input line, message below refers to column %u ***]",
329 RActual = fread (&SourceByte, 1, 1, SourceFile);
333 "[*** iASL: Read error on source code temp file %s ***]",
334 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
343 fprintf (OutputFile, "\n");
350 * Less verbose version of the error message, enabled via the
351 * -vi switch. The format is compatible with MS Visual Studio.
353 fprintf (OutputFile, "%s", Enode->Filename);
355 if (Enode->LineNumber)
357 fprintf (OutputFile, "(%u) : ",
363 /* NULL message ID, just print the raw message */
365 if (Enode->MessageId == 0)
367 fprintf (OutputFile, "%s\n", Enode->Message);
371 /* Decode the message ID */
373 if (Gbl_VerboseErrors)
375 fprintf (OutputFile, "%s %4.4d -",
376 AslErrorLevel[Enode->Level],
377 Enode->MessageId + ((Enode->Level+1) * 1000));
381 fprintf (OutputFile, "%s %4.4d:",
382 AslErrorLevelIde[Enode->Level],
383 Enode->MessageId + ((Enode->Level+1) * 1000));
386 MainMessage = AslMessages[Enode->MessageId];
387 ExtraMessage = Enode->Message;
389 if (Enode->LineNumber)
391 /* Main message: try to use string from AslMessages first */
398 MsgLength = strlen (MainMessage);
401 /* Use the secondary/extra message as main message */
403 MainMessage = Enode->Message;
409 MsgLength = strlen (MainMessage);
413 if (Gbl_VerboseErrors && !PrematureEOF)
417 fprintf (OutputFile, " %s",
422 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
423 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
425 if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
427 fprintf (OutputFile, "%*s%s",
428 (int) ((SourceColumn - 1) - ErrorColumn),
433 fprintf (OutputFile, "%*s %s",
434 (int) ((SourceColumn - ErrorColumn) + 1), "^",
441 fprintf (OutputFile, " %s", MainMessage);
444 /* Print the extra info message if present */
448 fprintf (OutputFile, " (%s)", ExtraMessage);
453 fprintf (OutputFile, " and premature End-Of-File");
456 fprintf (OutputFile, "\n");
457 if (Gbl_VerboseErrors)
459 fprintf (OutputFile, "\n");
464 fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
470 /*******************************************************************************
472 * FUNCTION: AePrintErrorLog
474 * PARAMETERS: FileId - Where to output the error log
478 * DESCRIPTION: Print the entire contents of the error log
480 ******************************************************************************/
486 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
489 /* Walk the error node list */
493 AePrintException (FileId, Enode, NULL);
499 /*******************************************************************************
501 * FUNCTION: AslCommonError2
503 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
504 * MessageId - Index into global message buffer
505 * LineNumber - Actual file line number
506 * Column - Column in current line
507 * SourceLine - Actual source code line
508 * Filename - source filename
509 * ExtraMessage - additional error message
513 * DESCRIPTION: Create a new error node and add it to the error log
515 ******************************************************************************/
527 char *MessageBuffer = NULL;
529 ASL_ERROR_MSG *Enode;
532 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
536 /* Allocate a buffer for the message and a new error node */
538 MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
540 /* Keep a copy of the extra message */
542 ACPI_STRCPY (MessageBuffer, ExtraMessage);
545 LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
546 ACPI_STRCPY (LineBuffer, SourceLine);
548 /* Initialize the error node */
552 Enode->Filename = Filename;
553 Enode->FilenameLength = strlen (Filename);
554 if (Enode->FilenameLength < 6)
556 Enode->FilenameLength = 6;
560 Enode->MessageId = MessageId;
561 Enode->Level = Level;
562 Enode->LineNumber = LineNumber;
563 Enode->LogicalLineNumber = LineNumber;
564 Enode->LogicalByteOffset = 0;
565 Enode->Column = Column;
566 Enode->Message = MessageBuffer;
567 Enode->SourceLine = LineBuffer;
569 /* Add the new node to the error node list */
571 AeAddToErrorLog (Enode);
575 /* stderr is a file, send error to it immediately */
577 AePrintException (ASL_FILE_STDERR, Enode, NULL);
580 Gbl_ExceptionCount[Level]++;
584 /*******************************************************************************
586 * FUNCTION: AslCommonError
588 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
589 * MessageId - Index into global message buffer
590 * CurrentLineNumber - Actual file line number
591 * LogicalLineNumber - Cumulative line number
592 * LogicalByteOffset - Byte offset in source file
593 * Column - Column in current line
594 * Filename - source filename
595 * ExtraMessage - additional error message
599 * DESCRIPTION: Create a new error node and add it to the error log
601 ******************************************************************************/
607 UINT32 CurrentLineNumber,
608 UINT32 LogicalLineNumber,
609 UINT32 LogicalByteOffset,
615 char *MessageBuffer = NULL;
616 ASL_ERROR_MSG *Enode;
619 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
623 /* Allocate a buffer for the message and a new error node */
625 MessageSize = strlen (ExtraMessage) + 1;
626 MessageBuffer = UtLocalCalloc (MessageSize);
628 /* Keep a copy of the extra message */
630 ACPI_STRCPY (MessageBuffer, ExtraMessage);
633 /* Initialize the error node */
637 Enode->Filename = Filename;
638 Enode->FilenameLength = strlen (Filename);
639 if (Enode->FilenameLength < 6)
641 Enode->FilenameLength = 6;
645 Enode->MessageId = MessageId;
646 Enode->Level = Level;
647 Enode->LineNumber = CurrentLineNumber;
648 Enode->LogicalLineNumber = LogicalLineNumber;
649 Enode->LogicalByteOffset = LogicalByteOffset;
650 Enode->Column = Column;
651 Enode->Message = MessageBuffer;
652 Enode->SourceLine = NULL;
654 /* Add the new node to the error node list */
656 AeAddToErrorLog (Enode);
660 /* stderr is a file, send error to it immediately */
662 AePrintException (ASL_FILE_STDERR, Enode, NULL);
665 Gbl_ExceptionCount[Level]++;
666 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
668 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
671 Gbl_NextError = Gbl_ErrorLog;
680 /*******************************************************************************
682 * FUNCTION: AslDisableException
684 * PARAMETERS: MessageIdString - ID to be disabled
688 * DESCRIPTION: Enter a message ID into the global disabled messages table
690 ******************************************************************************/
693 AslDisableException (
694 char *MessageIdString)
699 /* Convert argument to an integer and validate it */
701 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
703 if ((MessageId < 2000) || (MessageId > 5999))
705 printf ("\"%s\" is not a valid warning/remark ID\n",
707 return (AE_BAD_PARAMETER);
710 /* Insert value into the global disabled message array */
712 if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
714 printf ("Too many messages have been disabled (max %u)\n",
715 ASL_MAX_DISABLED_MESSAGES);
719 Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
720 Gbl_DisabledMessagesIndex++;
725 /*******************************************************************************
727 * FUNCTION: AslIsExceptionDisabled
729 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
730 * MessageId - Index into global message buffer
732 * RETURN: TRUE if exception/message should be ignored
734 * DESCRIPTION: Check if the user has specified options such that this
735 * exception should be ignored
737 ******************************************************************************/
740 AslIsExceptionDisabled (
744 UINT32 EncodedMessageId;
753 /* Check for global disable via -w1/-w2/-w3 options */
755 if (Level > Gbl_WarningLevel)
764 * Ignore this warning/remark if it has been disabled by
765 * the user (-vw option)
767 EncodedMessageId = MessageId + ((Level + 1) * 1000);
768 for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
770 /* Simple implementation via fixed array */
772 if (EncodedMessageId == Gbl_DisabledMessages[i])
787 /*******************************************************************************
791 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
792 * MessageId - Index into global message buffer
793 * Op - Parse node where error happened
794 * ExtraMessage - additional error message
798 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
799 * except the parser.)
801 ******************************************************************************/
807 ACPI_PARSE_OBJECT *Op,
811 /* Check if user wants to ignore this exception */
813 if (AslIsExceptionDisabled (Level, MessageId))
820 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
821 Op->Asl.LogicalLineNumber,
822 Op->Asl.LogicalByteOffset,
824 Op->Asl.Filename, ExtraMessage);
828 AslCommonError (Level, MessageId, 0,
829 0, 0, 0, NULL, ExtraMessage);
834 /*******************************************************************************
836 * FUNCTION: AslCoreSubsystemError
838 * PARAMETERS: Op - Parse node where error happened
839 * Status - The ACPI CA Exception
840 * ExtraMessage - additional error message
841 * Abort - TRUE -> Abort compilation
845 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
848 ******************************************************************************/
851 AslCoreSubsystemError (
852 ACPI_PARSE_OBJECT *Op,
858 sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
862 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
863 Op->Asl.LogicalLineNumber,
864 Op->Asl.LogicalByteOffset,
866 Op->Asl.Filename, MsgBuffer);
870 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
871 0, 0, 0, NULL, MsgBuffer);
881 /*******************************************************************************
883 * FUNCTION: AslCompilererror
885 * PARAMETERS: CompilerMessage - Error message from the parser
887 * RETURN: Status (0 for now)
889 * DESCRIPTION: Report an error situation discovered in a production
890 * NOTE: don't change the name of this function, it is called
891 * from the auto-generated parser.
893 ******************************************************************************/
897 const char *CompilerMessage)
900 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
901 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
902 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
903 ACPI_CAST_PTR (char, CompilerMessage));