1 /******************************************************************************
3 * Module Name: aslerror - Error handling and statistics
5 *****************************************************************************/
8 * Copyright (C) 2000 - 2015, 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 #include <contrib/dev/acpica/compiler/aslcompiler.h>
46 #define _COMPONENT ACPI_COMPILER
47 ACPI_MODULE_NAME ("aslerror")
49 /* Local prototypes */
53 ASL_ERROR_MSG *Enode);
56 /*******************************************************************************
64 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
67 ******************************************************************************/
74 AePrintErrorLog (ASL_FILE_STDERR);
77 /* Print error summary to stdout also */
79 AePrintErrorLog (ASL_FILE_STDOUT);
86 /*******************************************************************************
88 * FUNCTION: AeClearErrorLog
94 * DESCRIPTION: Empty the error list
96 ******************************************************************************/
102 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
105 /* Walk the error node list */
118 /*******************************************************************************
120 * FUNCTION: AeAddToErrorLog
122 * PARAMETERS: Enode - An error node to add to the log
126 * DESCRIPTION: Add a new error node to the error log. The error log is
127 * ordered by the "logical" line number (cumulative line number
128 * including all include files.)
130 ******************************************************************************/
134 ASL_ERROR_MSG *Enode)
140 /* If Gbl_ErrorLog is null, this is the first error node */
144 Gbl_ErrorLog = Enode;
149 * Walk error list until we find a line number greater than ours.
150 * List is sorted according to line number.
156 (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
162 /* Found our place in the list */
172 Gbl_ErrorLog = Enode;
177 /*******************************************************************************
179 * FUNCTION: AePrintException
181 * PARAMETERS: FileId - ID of output file
182 * Enode - Error node to print
183 * Header - Additional text before each message
187 * DESCRIPTION: Print the contents of an error node.
189 * NOTE: We don't use the FlxxxFile I/O functions here because on error
190 * they abort the compiler and call this function! Since we
191 * are reporting errors here, we ignore most output errors and
192 * just try to get out as much as we can.
194 ******************************************************************************/
199 ASL_ERROR_MSG *Enode,
206 const char *MainMessage;
211 FILE *SourceFile = NULL;
213 BOOLEAN PrematureEOF = FALSE;
223 * Only listing files have a header, and remarks/optimizations
228 /* Ignore remarks if requested */
230 switch (Enode->Level)
236 if (!Gbl_DisplayWarnings)
244 if (!Gbl_DisplayRemarks)
250 case ASL_OPTIMIZATION:
252 if (!Gbl_DisplayOptimizations)
264 /* Get the various required file handles */
266 OutputFile = Gbl_Files[FileId].Handle;
268 if (!Enode->SourceLine)
270 /* Use the merged header/source file if present, otherwise use input file */
272 SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
275 SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
280 /* Determine if the error occurred at source file EOF */
282 fseek (SourceFile, 0, SEEK_END);
283 FileSize = ftell (SourceFile);
285 if ((long) Enode->LogicalByteOffset >= FileSize)
294 fprintf (OutputFile, "%s", Header);
297 /* Print filename and line number if present and valid */
301 if (Gbl_VerboseErrors)
303 fprintf (OutputFile, "%-8s", Enode->Filename);
305 if (Enode->LineNumber)
307 if (Enode->SourceLine)
309 fprintf (OutputFile, " %6u: %s",
310 Enode->LineNumber, Enode->SourceLine);
314 fprintf (OutputFile, " %6u: ", Enode->LineNumber);
317 * If not at EOF, get the corresponding source code line and
318 * display it. Don't attempt this if we have a premature EOF
324 * Seek to the offset in the combined source file, read
325 * the source line, and write it to the output.
327 Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
332 "[*** iASL: Seek error on source code temp file %s ***]",
333 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
337 RActual = fread (&SourceByte, 1, 1, SourceFile);
341 "[*** iASL: Read error on source code temp file %s ***]",
342 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
346 /* Read/write the source line, up to the maximum line length */
348 while (RActual && SourceByte && (SourceByte != '\n'))
352 /* After the max line length, we will just read the line, no write */
354 if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
356 printf ("[*** iASL: Write error on output file ***]\n");
360 else if (Total == 256)
363 "\n[*** iASL: Very long input line, message below refers to column %u ***]",
367 RActual = fread (&SourceByte, 1, 1, SourceFile);
371 "[*** iASL: Read error on source code temp file %s ***]",
372 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
381 fprintf (OutputFile, "\n");
388 * Less verbose version of the error message, enabled via the
389 * -vi switch. The format is compatible with MS Visual Studio.
391 fprintf (OutputFile, "%s", Enode->Filename);
393 if (Enode->LineNumber)
395 fprintf (OutputFile, "(%u) : ",
401 /* If a NULL message ID, just print the raw message */
403 if (Enode->MessageId == 0)
405 fprintf (OutputFile, "%s\n", Enode->Message);
409 /* Decode the message ID */
411 fprintf (OutputFile, "%s %4.4d -",
412 AeDecodeExceptionLevel (Enode->Level),
413 AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
415 MainMessage = AeDecodeMessageId (Enode->MessageId);
416 ExtraMessage = Enode->Message;
418 /* If a NULL line number, just print the decoded message */
420 if (!Enode->LineNumber)
422 fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
426 MsgLength = strlen (MainMessage);
429 /* Use the secondary/extra message as main message */
431 MainMessage = Enode->Message;
437 MsgLength = strlen (MainMessage);
441 if (Gbl_VerboseErrors && !PrematureEOF)
445 fprintf (OutputFile, " %s",
450 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
451 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
453 if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
455 fprintf (OutputFile, "%*s%s",
456 (int) ((SourceColumn - 1) - ErrorColumn),
461 fprintf (OutputFile, "%*s %s",
462 (int) ((SourceColumn - ErrorColumn) + 1), "^",
469 fprintf (OutputFile, " %s", MainMessage);
472 /* Print the extra info message if present */
476 fprintf (OutputFile, " (%s)", ExtraMessage);
481 fprintf (OutputFile, " and premature End-Of-File");
484 fprintf (OutputFile, "\n");
485 if (Gbl_VerboseErrors)
487 fprintf (OutputFile, "\n");
492 /*******************************************************************************
494 * FUNCTION: AePrintErrorLog
496 * PARAMETERS: FileId - Where to output the error log
500 * DESCRIPTION: Print the entire contents of the error log
502 ******************************************************************************/
508 ASL_ERROR_MSG *Enode = Gbl_ErrorLog;
511 /* Walk the error node list */
515 AePrintException (FileId, Enode, NULL);
521 /*******************************************************************************
523 * FUNCTION: AslCommonError2
525 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
526 * MessageId - Index into global message buffer
527 * LineNumber - Actual file line number
528 * Column - Column in current line
529 * SourceLine - Actual source code line
530 * Filename - source filename
531 * ExtraMessage - additional error message
535 * DESCRIPTION: Create a new error node and add it to the error log
537 ******************************************************************************/
549 char *MessageBuffer = NULL;
551 ASL_ERROR_MSG *Enode;
554 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
558 /* Allocate a buffer for the message and a new error node */
560 MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
562 /* Keep a copy of the extra message */
564 ACPI_STRCPY (MessageBuffer, ExtraMessage);
567 LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
568 ACPI_STRCPY (LineBuffer, SourceLine);
570 /* Initialize the error node */
574 Enode->Filename = Filename;
575 Enode->FilenameLength = strlen (Filename);
576 if (Enode->FilenameLength < 6)
578 Enode->FilenameLength = 6;
582 Enode->MessageId = MessageId;
583 Enode->Level = Level;
584 Enode->LineNumber = LineNumber;
585 Enode->LogicalLineNumber = LineNumber;
586 Enode->LogicalByteOffset = 0;
587 Enode->Column = Column;
588 Enode->Message = MessageBuffer;
589 Enode->SourceLine = LineBuffer;
591 /* Add the new node to the error node list */
593 AeAddToErrorLog (Enode);
597 /* stderr is a file, send error to it immediately */
599 AePrintException (ASL_FILE_STDERR, Enode, NULL);
602 Gbl_ExceptionCount[Level]++;
606 /*******************************************************************************
608 * FUNCTION: AslCommonError
610 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
611 * MessageId - Index into global message buffer
612 * CurrentLineNumber - Actual file line number
613 * LogicalLineNumber - Cumulative line number
614 * LogicalByteOffset - Byte offset in source file
615 * Column - Column in current line
616 * Filename - source filename
617 * ExtraMessage - additional error message
621 * DESCRIPTION: Create a new error node and add it to the error log
623 ******************************************************************************/
629 UINT32 CurrentLineNumber,
630 UINT32 LogicalLineNumber,
631 UINT32 LogicalByteOffset,
636 char *MessageBuffer = NULL;
637 ASL_ERROR_MSG *Enode;
640 Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
644 /* Allocate a buffer for the message and a new error node */
646 MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
648 /* Keep a copy of the extra message */
650 ACPI_STRCPY (MessageBuffer, ExtraMessage);
653 /* Initialize the error node */
657 Enode->Filename = Filename;
658 Enode->FilenameLength = strlen (Filename);
659 if (Enode->FilenameLength < 6)
661 Enode->FilenameLength = 6;
665 Enode->MessageId = MessageId;
666 Enode->Level = Level;
667 Enode->LineNumber = CurrentLineNumber;
668 Enode->LogicalLineNumber = LogicalLineNumber;
669 Enode->LogicalByteOffset = LogicalByteOffset;
670 Enode->Column = Column;
671 Enode->Message = MessageBuffer;
672 Enode->SourceLine = NULL;
674 /* Add the new node to the error node list */
676 AeAddToErrorLog (Enode);
680 /* stderr is a file, send error to it immediately */
682 AePrintException (ASL_FILE_STDERR, Enode, NULL);
685 Gbl_ExceptionCount[Level]++;
686 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
688 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
691 Gbl_NextError = Gbl_ErrorLog;
700 /*******************************************************************************
702 * FUNCTION: AslDisableException
704 * PARAMETERS: MessageIdString - ID to be disabled
708 * DESCRIPTION: Enter a message ID into the global disabled messages table
710 ******************************************************************************/
713 AslDisableException (
714 char *MessageIdString)
719 /* Convert argument to an integer and validate it */
721 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
723 if ((MessageId < 2000) || (MessageId > 5999))
725 printf ("\"%s\" is not a valid warning/remark ID\n",
727 return (AE_BAD_PARAMETER);
730 /* Insert value into the global disabled message array */
732 if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
734 printf ("Too many messages have been disabled (max %u)\n",
735 ASL_MAX_DISABLED_MESSAGES);
739 Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
740 Gbl_DisabledMessagesIndex++;
745 /*******************************************************************************
747 * FUNCTION: AslIsExceptionDisabled
749 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
750 * MessageId - Index into global message buffer
752 * RETURN: TRUE if exception/message should be ignored
754 * DESCRIPTION: Check if the user has specified options such that this
755 * exception should be ignored
757 ******************************************************************************/
760 AslIsExceptionDisabled (
764 UINT32 EncodedMessageId;
773 /* Check for global disable via -w1/-w2/-w3 options */
775 if (Level > Gbl_WarningLevel)
784 * Ignore this warning/remark if it has been disabled by
785 * the user (-vw option)
787 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
788 for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
790 /* Simple implementation via fixed array */
792 if (EncodedMessageId == Gbl_DisabledMessages[i])
807 /*******************************************************************************
811 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
812 * MessageId - Index into global message buffer
813 * Op - Parse node where error happened
814 * ExtraMessage - additional error message
818 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
819 * except the parser.)
821 ******************************************************************************/
827 ACPI_PARSE_OBJECT *Op,
831 /* Check if user wants to ignore this exception */
833 if (Gbl_AllExceptionsDisabled ||
834 AslIsExceptionDisabled (Level, MessageId))
841 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
842 Op->Asl.LogicalLineNumber,
843 Op->Asl.LogicalByteOffset,
845 Op->Asl.Filename, ExtraMessage);
849 AslCommonError (Level, MessageId, 0,
850 0, 0, 0, NULL, ExtraMessage);
855 /*******************************************************************************
857 * FUNCTION: AslCoreSubsystemError
859 * PARAMETERS: Op - Parse node where error happened
860 * Status - The ACPICA Exception
861 * ExtraMessage - additional error message
862 * Abort - TRUE -> Abort compilation
866 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
869 ******************************************************************************/
872 AslCoreSubsystemError (
873 ACPI_PARSE_OBJECT *Op,
879 sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
883 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
884 Op->Asl.LogicalLineNumber,
885 Op->Asl.LogicalByteOffset,
887 Op->Asl.Filename, MsgBuffer);
891 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
892 0, 0, 0, NULL, MsgBuffer);
902 /*******************************************************************************
904 * FUNCTION: AslCompilererror
906 * PARAMETERS: CompilerMessage - Error message from the parser
908 * RETURN: Status (0 for now)
910 * DESCRIPTION: Report an error situation discovered in a production
911 * NOTE: don't change the name of this function, it is called
912 * from the auto-generated parser.
914 ******************************************************************************/
918 const char *CompilerMessage)
923 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
924 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
925 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
926 ACPI_CAST_PTR (char, CompilerMessage));