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 "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
,
614 char *MessageBuffer
= NULL
;
615 ASL_ERROR_MSG
*Enode
;
618 Enode
= UtLocalCalloc (sizeof (ASL_ERROR_MSG
));
622 /* Allocate a buffer for the message and a new error node */
624 MessageBuffer
= UtLocalCalloc (strlen (ExtraMessage
) + 1);
626 /* Keep a copy of the extra message */
628 ACPI_STRCPY (MessageBuffer
, ExtraMessage
);
631 /* Initialize the error node */
635 Enode
->Filename
= Filename
;
636 Enode
->FilenameLength
= strlen (Filename
);
637 if (Enode
->FilenameLength
< 6)
639 Enode
->FilenameLength
= 6;
643 Enode
->MessageId
= MessageId
;
644 Enode
->Level
= Level
;
645 Enode
->LineNumber
= CurrentLineNumber
;
646 Enode
->LogicalLineNumber
= LogicalLineNumber
;
647 Enode
->LogicalByteOffset
= LogicalByteOffset
;
648 Enode
->Column
= Column
;
649 Enode
->Message
= MessageBuffer
;
650 Enode
->SourceLine
= NULL
;
652 /* Add the new node to the error node list */
654 AeAddToErrorLog (Enode
);
658 /* stderr is a file, send error to it immediately */
660 AePrintException (ASL_FILE_STDERR
, Enode
, NULL
);
663 Gbl_ExceptionCount
[Level
]++;
664 if (Gbl_ExceptionCount
[ASL_ERROR
] > ASL_MAX_ERROR_COUNT
)
666 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT
);
669 Gbl_NextError
= Gbl_ErrorLog
;
678 /*******************************************************************************
680 * FUNCTION: AslDisableException
682 * PARAMETERS: MessageIdString - ID to be disabled
686 * DESCRIPTION: Enter a message ID into the global disabled messages table
688 ******************************************************************************/
691 AslDisableException (
692 char *MessageIdString
)
697 /* Convert argument to an integer and validate it */
699 MessageId
= (UINT32
) strtoul (MessageIdString
, NULL
, 0);
701 if ((MessageId
< 2000) || (MessageId
> 5999))
703 printf ("\"%s\" is not a valid warning/remark ID\n",
705 return (AE_BAD_PARAMETER
);
708 /* Insert value into the global disabled message array */
710 if (Gbl_DisabledMessagesIndex
>= ASL_MAX_DISABLED_MESSAGES
)
712 printf ("Too many messages have been disabled (max %u)\n",
713 ASL_MAX_DISABLED_MESSAGES
);
717 Gbl_DisabledMessages
[Gbl_DisabledMessagesIndex
] = MessageId
;
718 Gbl_DisabledMessagesIndex
++;
723 /*******************************************************************************
725 * FUNCTION: AslIsExceptionDisabled
727 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
728 * MessageId - Index into global message buffer
730 * RETURN: TRUE if exception/message should be ignored
732 * DESCRIPTION: Check if the user has specified options such that this
733 * exception should be ignored
735 ******************************************************************************/
738 AslIsExceptionDisabled (
742 UINT32 EncodedMessageId
;
751 /* Check for global disable via -w1/-w2/-w3 options */
753 if (Level
> Gbl_WarningLevel
)
762 * Ignore this warning/remark if it has been disabled by
763 * the user (-vw option)
765 EncodedMessageId
= MessageId
+ ((Level
+ 1) * 1000);
766 for (i
= 0; i
< Gbl_DisabledMessagesIndex
; i
++)
768 /* Simple implementation via fixed array */
770 if (EncodedMessageId
== Gbl_DisabledMessages
[i
])
785 /*******************************************************************************
789 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
790 * MessageId - Index into global message buffer
791 * Op - Parse node where error happened
792 * ExtraMessage - additional error message
796 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
797 * except the parser.)
799 ******************************************************************************/
805 ACPI_PARSE_OBJECT
*Op
,
809 /* Check if user wants to ignore this exception */
811 if (AslIsExceptionDisabled (Level
, MessageId
))
818 AslCommonError (Level
, MessageId
, Op
->Asl
.LineNumber
,
819 Op
->Asl
.LogicalLineNumber
,
820 Op
->Asl
.LogicalByteOffset
,
822 Op
->Asl
.Filename
, ExtraMessage
);
826 AslCommonError (Level
, MessageId
, 0,
827 0, 0, 0, NULL
, ExtraMessage
);
832 /*******************************************************************************
834 * FUNCTION: AslCoreSubsystemError
836 * PARAMETERS: Op - Parse node where error happened
837 * Status - The ACPI CA Exception
838 * ExtraMessage - additional error message
839 * Abort - TRUE -> Abort compilation
843 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
846 ******************************************************************************/
849 AslCoreSubsystemError (
850 ACPI_PARSE_OBJECT
*Op
,
856 sprintf (MsgBuffer
, "%s %s", AcpiFormatException (Status
), ExtraMessage
);
860 AslCommonError (ASL_ERROR
, ASL_MSG_CORE_EXCEPTION
, Op
->Asl
.LineNumber
,
861 Op
->Asl
.LogicalLineNumber
,
862 Op
->Asl
.LogicalByteOffset
,
864 Op
->Asl
.Filename
, MsgBuffer
);
868 AslCommonError (ASL_ERROR
, ASL_MSG_CORE_EXCEPTION
, 0,
869 0, 0, 0, NULL
, MsgBuffer
);
879 /*******************************************************************************
881 * FUNCTION: AslCompilererror
883 * PARAMETERS: CompilerMessage - Error message from the parser
885 * RETURN: Status (0 for now)
887 * DESCRIPTION: Report an error situation discovered in a production
888 * NOTE: don't change the name of this function, it is called
889 * from the auto-generated parser.
891 ******************************************************************************/
895 const char *CompilerMessage
)
898 AslCommonError (ASL_ERROR
, ASL_MSG_SYNTAX
, Gbl_CurrentLineNumber
,
899 Gbl_LogicalLineNumber
, Gbl_CurrentLineOffset
,
900 Gbl_CurrentColumn
, Gbl_Files
[ASL_FILE_INPUT
].Filename
,
901 ACPI_CAST_PTR (char, CompilerMessage
));