aslerror.c revision 1.1.1.16 1 /******************************************************************************
2 *
3 * Module Name: aslerror - Error handling and statistics
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2019, Intel Corp.
9 * All rights reserved.
10 *
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
13 * are met:
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.
25 *
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.
29 *
30 * NO WARRANTY
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.
42 */
43
44 #include "aslcompiler.h"
45
46 #define _COMPONENT ACPI_COMPILER
47 ACPI_MODULE_NAME ("aslerror")
48
49 /* Local prototypes */
50
51 static void
52 AeAddToErrorLog (
53 ASL_ERROR_MSG *Enode);
54
55 static BOOLEAN
56 AslIsExceptionExpected (
57 UINT8 Level,
58 UINT16 MessageId);
59
60 static BOOLEAN
61 AslIsExceptionDisabled (
62 UINT8 Level,
63 UINT16 MessageId);
64
65 static void AslInitEnode (
66 ASL_ERROR_MSG **Enode,
67 UINT8 Level,
68 UINT16 MessageId,
69 UINT32 LineNumber,
70 UINT32 LogicalLineNumber,
71 UINT32 LogicalByteOffset,
72 UINT32 Column,
73 char *Filename,
74 char *Message,
75 char *SourceLine,
76 ASL_ERROR_MSG *SubError);
77
78 static void
79 AslLogNewError (
80 UINT8 Level,
81 UINT16 MessageId,
82 UINT32 LineNumber,
83 UINT32 LogicalLineNumber,
84 UINT32 LogicalByteOffset,
85 UINT32 Column,
86 char *Filename,
87 char *Message,
88 char *SourceLine,
89 ASL_ERROR_MSG *SubError);
90
91 static void
92 AePrintSubError (
93 FILE *OutputFile,
94 ASL_ERROR_MSG *Enode);
95
96 static UINT8
97 GetModifiedLevel (
98 UINT8 Level,
99 UINT16 MessageId);
100
101
102 /*******************************************************************************
103 *
104 * FUNCTION: AslAbort
105 *
106 * PARAMETERS: None
107 *
108 * RETURN: None
109 *
110 * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
111 * I/O errors.
112 *
113 ******************************************************************************/
114
115 void
116 AslAbort (
117 void)
118 {
119
120 AePrintErrorLog (ASL_FILE_STDERR);
121 if (AslGbl_DebugFlag)
122 {
123 /* Print error summary to stdout also */
124
125 AePrintErrorLog (ASL_FILE_STDOUT);
126 }
127
128 exit (1);
129 }
130
131
132 /*******************************************************************************
133 *
134 * FUNCTION: AeClearErrorLog
135 *
136 * PARAMETERS: None
137 *
138 * RETURN: None
139 *
140 * DESCRIPTION: Empty the error list
141 *
142 ******************************************************************************/
143
144 void
145 AeClearErrorLog (
146 void)
147 {
148 ASL_ERROR_MSG *Enode = AslGbl_ErrorLog;
149 ASL_ERROR_MSG *Next;
150
151
152 /* Walk the error node list */
153
154 while (Enode)
155 {
156 Next = Enode->Next;
157 ACPI_FREE (Enode);
158 Enode = Next;
159 }
160
161 AslGbl_ErrorLog = NULL;
162 }
163
164
165 /*******************************************************************************
166 *
167 * FUNCTION: AeAddToErrorLog
168 *
169 * PARAMETERS: Enode - An error node to add to the log
170 *
171 * RETURN: None
172 *
173 * DESCRIPTION: Add a new error node to the error log. The error log is
174 * ordered by the "logical" line number (cumulative line number
175 * including all include files.)
176 *
177 ******************************************************************************/
178
179 static void
180 AeAddToErrorLog (
181 ASL_ERROR_MSG *Enode)
182 {
183 ASL_ERROR_MSG *Next;
184 ASL_ERROR_MSG *Prev;
185
186
187 /* If Gbl_ErrorLog is null, this is the first error node */
188
189 if (!AslGbl_ErrorLog)
190 {
191 AslGbl_ErrorLog = Enode;
192 return;
193 }
194
195 /*
196 * Walk error list until we find a line number greater than ours.
197 * List is sorted according to line number.
198 */
199 Prev = NULL;
200 Next = AslGbl_ErrorLog;
201
202 while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
203 {
204 Prev = Next;
205 Next = Next->Next;
206 }
207
208 /* Found our place in the list */
209
210 Enode->Next = Next;
211
212 if (Prev)
213 {
214 Prev->Next = Enode;
215 }
216 else
217 {
218 AslGbl_ErrorLog = Enode;
219 }
220 }
221
222
223 /*******************************************************************************
224 *
225 * FUNCTION: AeDecodeErrorMessageId
226 *
227 * PARAMETERS: OutputFile - Output file
228 * Enode - Error node to print
229 * PrematureEOF - True = PrematureEOF has been reached
230 * Total - Total length of line
231 *
232 * RETURN: None
233 *
234 * DESCRIPTION: Print the source line of an error.
235 *
236 ******************************************************************************/
237
238 static void
239 AeDecodeErrorMessageId (
240 FILE *OutputFile,
241 ASL_ERROR_MSG *Enode,
242 BOOLEAN PrematureEOF,
243 UINT32 Total)
244 {
245 UINT32 MsgLength;
246 const char *MainMessage;
247 char *ExtraMessage;
248 UINT32 SourceColumn;
249 UINT32 ErrorColumn;
250
251
252 fprintf (OutputFile, "%s %4.4d -",
253 AeDecodeExceptionLevel (Enode->Level),
254 AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
255
256 MainMessage = AeDecodeMessageId (Enode->MessageId);
257 ExtraMessage = Enode->Message;
258
259 /* If a NULL line number, just print the decoded message */
260
261 if (!Enode->LineNumber)
262 {
263 fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
264 return;
265 }
266
267 MsgLength = strlen (MainMessage);
268 if (MsgLength == 0)
269 {
270 /* Use the secondary/extra message as main message */
271
272 MainMessage = Enode->Message;
273 if (!MainMessage)
274 {
275 MainMessage = "";
276 }
277
278 MsgLength = strlen (MainMessage);
279 ExtraMessage = NULL;
280 }
281
282 if (AslGbl_VerboseErrors && !PrematureEOF)
283 {
284 if (Total >= 256)
285 {
286 fprintf (OutputFile, " %s",
287 MainMessage);
288 }
289 else
290 {
291 SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
292 ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
293
294 if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
295 {
296 fprintf (OutputFile, "%*s%s",
297 (int) ((SourceColumn - 1) - ErrorColumn),
298 MainMessage, " ^ ");
299 }
300 else
301 {
302 fprintf (OutputFile, "%*s %s",
303 (int) ((SourceColumn - ErrorColumn) + 1), "^",
304 MainMessage);
305 }
306 }
307 }
308 else
309 {
310 fprintf (OutputFile, " %s", MainMessage);
311 }
312
313 /* Print the extra info message if present */
314
315 if (ExtraMessage)
316 {
317 fprintf (OutputFile, " (%s)", ExtraMessage);
318 }
319
320 if (PrematureEOF)
321 {
322 fprintf (OutputFile, " and premature End-Of-File");
323 }
324
325 fprintf (OutputFile, "\n");
326 if (AslGbl_VerboseErrors && !Enode->SubError)
327 {
328 fprintf (OutputFile, "\n");
329 }
330 }
331
332
333 /*******************************************************************************
334 *
335 * FUNCTION: AePrintErrorSourceLine
336 *
337 * PARAMETERS: OutputFile - Output file
338 * Enode - Error node to print
339 * PrematureEOF - True = PrematureEOF has been reached
340 * Total - Number of characters printed so far
341 *
342 *
343 * RETURN: Status
344 *
345 * DESCRIPTION: Print the source line of an error.
346 *
347 ******************************************************************************/
348
349 static ACPI_STATUS
350 AePrintErrorSourceLine (
351 FILE *OutputFile,
352 ASL_ERROR_MSG *Enode,
353 BOOLEAN *PrematureEOF,
354 UINT32 *Total)
355 {
356 UINT8 SourceByte;
357 int Actual;
358 size_t RActual;
359 FILE *SourceFile = NULL;
360 long FileSize;
361
362
363 if (!Enode->SourceLine)
364 {
365 /*
366 * Use the merged header/source file if present, otherwise
367 * use input file
368 */
369 SourceFile = FlGetFileHandle (ASL_FILE_SOURCE_OUTPUT,
370 ASL_FILE_SOURCE_OUTPUT, Enode->SourceFilename);
371 if (!SourceFile)
372 {
373 SourceFile = FlGetFileHandle (ASL_FILE_INPUT,
374 ASL_FILE_INPUT, Enode->Filename);
375 }
376
377 if (SourceFile)
378 {
379 /* Determine if the error occurred at source file EOF */
380
381 fseek (SourceFile, 0, SEEK_END);
382 FileSize = ftell (SourceFile);
383
384 if ((long) Enode->LogicalByteOffset >= FileSize)
385 {
386 *PrematureEOF = TRUE;
387 }
388 }
389 else
390 {
391 fprintf (OutputFile,
392 "[*** iASL: Source File Does not exist ***]\n");
393 return AE_IO_ERROR;
394 }
395 }
396
397 /* Print filename and line number if present and valid */
398
399 if (AslGbl_VerboseErrors)
400 {
401 fprintf (OutputFile, "%-8s", Enode->Filename);
402
403 if (Enode->SourceLine && Enode->LineNumber)
404 {
405 fprintf (OutputFile, " %6u: %s",
406 Enode->LineNumber, Enode->SourceLine);
407 }
408 else if (Enode->LineNumber)
409 {
410 fprintf (OutputFile, " %6u: ", Enode->LineNumber);
411
412 /*
413 * If not at EOF, get the corresponding source code line
414 * and display it. Don't attempt this if we have a
415 * premature EOF condition.
416 */
417 if (*PrematureEOF)
418 {
419 fprintf (OutputFile, "\n");
420 return AE_OK;
421 }
422
423 /*
424 * Seek to the offset in the combined source file,
425 * read the source line, and write it to the output.
426 */
427 Actual = fseek (SourceFile,
428 (long) Enode->LogicalByteOffset, (int) SEEK_SET);
429 if (Actual)
430 {
431 fprintf (OutputFile,
432 "[*** iASL: Seek error on source code temp file %s ***]",
433 AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
434
435 fprintf (OutputFile, "\n");
436 return AE_OK;
437 }
438 RActual = fread (&SourceByte, 1, 1, SourceFile);
439 if (RActual != 1)
440 {
441 fprintf (OutputFile,
442 "[*** iASL: Read error on source code temp file %s ***]",
443 AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
444 return AE_IO_ERROR;
445 }
446
447 /* Read/write the source line, up to the maximum line length */
448
449 while (RActual && SourceByte && (SourceByte != '\n'))
450 {
451 if (*Total < 256)
452 {
453 /* After the max line length, we will just read the line, no write */
454
455 if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
456 {
457 printf ("[*** iASL: Write error on output file ***]\n");
458 return AE_IO_ERROR;
459 }
460 }
461 else if (*Total == 256)
462 {
463 fprintf (OutputFile,
464 "\n[*** iASL: Very long input line, message below refers to column %u ***]",
465 Enode->Column);
466 }
467
468 RActual = fread (&SourceByte, 1, 1, SourceFile);
469 if (RActual != 1)
470 {
471 fprintf (OutputFile,
472 "[*** iASL: Read error on source code temp file %s ***]",
473 AslGbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
474
475 return AE_IO_ERROR;
476 }
477 *Total += 1;
478 }
479
480 fprintf (OutputFile, "\n");
481 }
482 }
483 else
484 {
485 /*
486 * Less verbose version of the error message, enabled via the
487 * -vi switch. The format is compatible with MS Visual Studio.
488 */
489 fprintf (OutputFile, "%s", Enode->Filename);
490
491 if (Enode->LineNumber)
492 {
493 fprintf (OutputFile, "(%u) : ",
494 Enode->LineNumber);
495 }
496 }
497
498 return AE_OK;
499 }
500
501 /*******************************************************************************
502 *
503 * FUNCTION: AePrintException
504 *
505 * PARAMETERS: FileId - ID of output file
506 * Enode - Error node to print
507 * Header - Additional text before each message
508 *
509 * RETURN: None
510 *
511 * DESCRIPTION: Print the contents of an error node.
512 *
513 * NOTE: We don't use the FlxxxFile I/O functions here because on error
514 * they abort the compiler and call this function! Since we
515 * are reporting errors here, we ignore most output errors and
516 * just try to get out as much as we can.
517 *
518 ******************************************************************************/
519
520 void
521 AePrintException (
522 UINT32 FileId,
523 ASL_ERROR_MSG *Enode,
524 char *Header)
525 {
526 FILE *OutputFile;
527 BOOLEAN PrematureEOF = FALSE;
528 UINT32 Total = 0;
529 ACPI_STATUS Status;
530 ASL_ERROR_MSG *Child = Enode->SubError;
531
532
533 if (AslGbl_NoErrors)
534 {
535 return;
536 }
537
538 /*
539 * Only listing files have a header, and remarks/optimizations
540 * are always output
541 */
542 if (!Header)
543 {
544 /* Ignore remarks if requested */
545
546 switch (Enode->Level)
547 {
548 case ASL_WARNING:
549 case ASL_WARNING2:
550 case ASL_WARNING3:
551
552 if (!AslGbl_DisplayWarnings)
553 {
554 return;
555 }
556 break;
557
558 case ASL_REMARK:
559
560 if (!AslGbl_DisplayRemarks)
561 {
562 return;
563 }
564 break;
565
566 case ASL_OPTIMIZATION:
567
568 if (!AslGbl_DisplayOptimizations)
569 {
570 return;
571 }
572 break;
573
574 default:
575
576 break;
577 }
578 }
579
580 /* Get the various required file handles */
581
582 OutputFile = AslGbl_Files[FileId].Handle;
583
584 if (Header)
585 {
586 fprintf (OutputFile, "%s", Header);
587 }
588
589 if (!Enode->Filename)
590 {
591 AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
592 return;
593 }
594
595 Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
596 if (ACPI_FAILURE (Status))
597 {
598 return;
599 }
600
601 /* If a NULL message ID, just print the raw message */
602
603 if (Enode->MessageId == 0)
604 {
605 fprintf (OutputFile, "%s\n", Enode->Message);
606 return;
607 }
608
609 AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
610
611 while (Child)
612 {
613 fprintf (OutputFile, "\n");
614 AePrintSubError (OutputFile, Child);
615 Child = Child->SubError;
616 }
617 }
618
619
620 /*******************************************************************************
621 *
622 * FUNCTION: AePrintSubError
623 *
624 * PARAMETERS: OutputFile - Output file
625 * Enode - Error node to print
626 *
627 * RETURN: None
628 *
629 * DESCRIPTION: Print the contents of an error node. This function is tailored
630 * to print error nodes that are SubErrors within ASL_ERROR_MSG
631 *
632 ******************************************************************************/
633
634 static void
635 AePrintSubError (
636 FILE *OutputFile,
637 ASL_ERROR_MSG *Enode)
638 {
639 UINT32 Total = 0;
640 BOOLEAN PrematureEOF = FALSE;
641 const char *MainMessage;
642
643
644 MainMessage = AeDecodeMessageId (Enode->MessageId);
645
646 fprintf (OutputFile, " %s%s", MainMessage, "\n ");
647 (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
648 fprintf (OutputFile, "\n");
649 }
650
651
652 /*******************************************************************************
653 *
654 * FUNCTION: AePrintErrorLog
655 *
656 * PARAMETERS: FileId - Where to output the error log
657 *
658 * RETURN: None
659 *
660 * DESCRIPTION: Print the entire contents of the error log
661 *
662 ******************************************************************************/
663
664 void
665 AePrintErrorLog (
666 UINT32 FileId)
667 {
668 ASL_ERROR_MSG *Enode = AslGbl_ErrorLog;
669
670
671 /* Walk the error node list */
672
673 while (Enode)
674 {
675 AePrintException (FileId, Enode, NULL);
676 Enode = Enode->Next;
677 }
678 }
679
680
681 /*******************************************************************************
682 *
683 * FUNCTION: AslInitEnode
684 *
685 * PARAMETERS: InputEnode - Input Error node to initialize
686 * Level - Seriousness (Warning/error, etc.)
687 * MessageId - Index into global message buffer
688 * CurrentLineNumber - Actual file line number
689 * LogicalLineNumber - Cumulative line number
690 * LogicalByteOffset - Byte offset in source file
691 * Column - Column in current line
692 * Filename - Source filename
693 * ExtraMessage - Additional error message
694 * SourceLine - Line of error source code
695 * SubError - SubError of this InputEnode
696 *
697 * RETURN: None
698 *
699 * DESCRIPTION: Initialize an Error node
700 *
701 ******************************************************************************/
702
703 static void AslInitEnode (
704 ASL_ERROR_MSG **InputEnode,
705 UINT8 Level,
706 UINT16 MessageId,
707 UINT32 LineNumber,
708 UINT32 LogicalLineNumber,
709 UINT32 LogicalByteOffset,
710 UINT32 Column,
711 char *Filename,
712 char *ExtraMessage,
713 char *SourceLine,
714 ASL_ERROR_MSG *SubError)
715 {
716 ASL_ERROR_MSG *Enode;
717 ASL_GLOBAL_FILE_NODE *FileNode;
718
719
720 *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
721 Enode = *InputEnode;
722 Enode->Level = Level;
723 Enode->MessageId = MessageId;
724 Enode->LineNumber = LineNumber;
725 Enode->LogicalLineNumber = LogicalLineNumber;
726 Enode->LogicalByteOffset = LogicalByteOffset;
727 Enode->Column = Column;
728 Enode->SubError = SubError;
729 Enode->Message = NULL;
730 Enode->SourceLine = NULL;
731 Enode->Filename = NULL;
732
733 if (ExtraMessage)
734 {
735 /* Allocate a buffer for the message and a new error node */
736
737 Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1);
738
739 /* Keep a copy of the extra message */
740
741 strcpy (Enode->Message, ExtraMessage);
742 }
743
744 if (SourceLine)
745 {
746 Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1);
747 strcpy (Enode->SourceLine, SourceLine);
748 }
749
750
751 if (Filename)
752 {
753 Enode->Filename = Filename;
754 Enode->FilenameLength = strlen (Filename);
755 if (Enode->FilenameLength < 6)
756 {
757 Enode->FilenameLength = 6;
758 }
759
760 /*
761 * Attempt to get the file node of the filename listed in the parse
762 * node. If the name doesn't exist in the global file node, it is
763 * because the file is included by #include or ASL include. In this
764 * case, get the current file node. The source output of the current
765 * file will contain the contents of the file listed in the parse node.
766 */
767 FileNode = FlGetFileNode (ASL_FILE_INPUT, Filename);
768 if (!FileNode)
769 {
770 FileNode = FlGetCurrentFileNode ();
771 }
772
773 Enode->SourceFilename =
774 FileNode->Files[ASL_FILE_SOURCE_OUTPUT].Filename;
775 }
776 }
777
778
779 /*******************************************************************************
780 *
781 * FUNCTION: AslCommonError2
782 *
783 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
784 * MessageId - Index into global message buffer
785 * LineNumber - Actual file line number
786 * Column - Column in current line
787 * SourceLine - Actual source code line
788 * Filename - Source filename
789 * ExtraMessage - Additional error message
790 *
791 * RETURN: None
792 *
793 * DESCRIPTION: Create a new error node and add it to the error log
794 *
795 ******************************************************************************/
796
797 void
798 AslCommonError2 (
799 UINT8 Level,
800 UINT16 MessageId,
801 UINT32 LineNumber,
802 UINT32 Column,
803 char *SourceLine,
804 char *Filename,
805 char *ExtraMessage)
806 {
807 AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column,
808 Filename, ExtraMessage, SourceLine, NULL);
809 }
810
811
812 /*******************************************************************************
813 *
814 * FUNCTION: AslCommonError
815 *
816 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
817 * MessageId - Index into global message buffer
818 * CurrentLineNumber - Actual file line number
819 * LogicalLineNumber - Cumulative line number
820 * LogicalByteOffset - Byte offset in source file
821 * Column - Column in current line
822 * Filename - Source filename
823 * ExtraMessage - Additional error message
824 *
825 * RETURN: None
826 *
827 * DESCRIPTION: Create a new error node and add it to the error log
828 *
829 ******************************************************************************/
830
831 void
832 AslCommonError (
833 UINT8 Level,
834 UINT16 MessageId,
835 UINT32 CurrentLineNumber,
836 UINT32 LogicalLineNumber,
837 UINT32 LogicalByteOffset,
838 UINT32 Column,
839 char *Filename,
840 char *ExtraMessage)
841 {
842 /* Check if user wants to ignore this exception */
843
844 if (AslIsExceptionIgnored (Level, MessageId))
845 {
846 return;
847 }
848
849 AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
850 LogicalByteOffset, Column, Filename, ExtraMessage,
851 NULL, NULL);
852 }
853
854
855 /*******************************************************************************
856 *
857 * FUNCTION: AslLogNewError
858 *
859 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
860 * MessageId - Index into global message buffer
861 * CurrentLineNumber - Actual file line number
862 * LogicalLineNumber - Cumulative line number
863 * LogicalByteOffset - Byte offset in source file
864 * Column - Column in current line
865 * Filename - Source filename
866 * Message - Additional error message
867 * SourceLine - Actual line of source code
868 * SubError - Sub-error associated with this error
869 *
870 * RETURN: None
871 *
872 * DESCRIPTION: Create a new error node and add it to the error log
873 *
874 ******************************************************************************/
875 static void
876 AslLogNewError (
877 UINT8 Level,
878 UINT16 MessageId,
879 UINT32 LineNumber,
880 UINT32 LogicalLineNumber,
881 UINT32 LogicalByteOffset,
882 UINT32 Column,
883 char *Filename,
884 char *Message,
885 char *SourceLine,
886 ASL_ERROR_MSG *SubError)
887 {
888 ASL_ERROR_MSG *Enode = NULL;
889 UINT8 ModifiedLevel = GetModifiedLevel (Level, MessageId);
890
891
892 AslInitEnode (&Enode, ModifiedLevel, MessageId, LineNumber,
893 LogicalLineNumber, LogicalByteOffset, Column, Filename, Message,
894 SourceLine, SubError);
895
896 /* Add the new node to the error node list */
897
898 AeAddToErrorLog (Enode);
899
900 if (AslGbl_DebugFlag)
901 {
902 /* stderr is a file, send error to it immediately */
903
904 AePrintException (ASL_FILE_STDERR, Enode, NULL);
905 }
906
907 AslGbl_ExceptionCount[ModifiedLevel]++;
908 if (!AslGbl_IgnoreErrors && AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
909 {
910 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
911
912 AslGbl_SourceLine = 0;
913 AslGbl_NextError = AslGbl_ErrorLog;
914 CmCleanupAndExit ();
915 exit(1);
916 }
917
918 return;
919 }
920
921
922 /*******************************************************************************
923 *
924 * FUNCTION: GetModifiedLevel
925 *
926 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
927 * MessageId - Index into global message buffer
928 *
929 * RETURN: UINT8 - Modified level
930 *
931 * DESCRIPTION: Get the modified level of exception codes that are reported as
932 * errors from the -ww option.
933 *
934 ******************************************************************************/
935
936 static UINT8
937 GetModifiedLevel (
938 UINT8 Level,
939 UINT16 MessageId)
940 {
941 UINT16 i;
942 UINT16 ExceptionCode;
943
944
945 ExceptionCode = AeBuildFullExceptionCode (Level, MessageId);
946
947 for (i = 0; i < AslGbl_ElevatedMessagesIndex; i++)
948 {
949 if (ExceptionCode == AslGbl_ElevatedMessages[i])
950 {
951 return (ASL_ERROR);
952 }
953 }
954
955 return (Level);
956 }
957
958
959 /*******************************************************************************
960 *
961 * FUNCTION: AslIsExceptionIgnored
962 *
963 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
964 * MessageId - Index into global message buffer
965 *
966 * RETURN: BOOLEAN
967 *
968 * DESCRIPTION: Check if a particular exception is ignored. In this case it
969 * means that the exception is (expected or disabled.
970 *
971 ******************************************************************************/
972
973 BOOLEAN
974 AslIsExceptionIgnored (
975 UINT8 Level,
976 UINT16 MessageId)
977 {
978 BOOLEAN ExceptionIgnored;
979
980
981 /* Note: this allows exception to be disabled and expected */
982
983 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
984 ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId);
985
986 return (AslGbl_AllExceptionsDisabled || ExceptionIgnored);
987 }
988
989
990 /*******************************************************************************
991 *
992 * FUNCTION: AslCheckExpectException
993 *
994 * PARAMETERS: none
995 *
996 * RETURN: none
997 *
998 * DESCRIPTION: Check the global expected messages table and raise an error
999 * for each message that has not been received.
1000 *
1001 ******************************************************************************/
1002
1003 void
1004 AslCheckExpectedExceptions (
1005 void)
1006 {
1007 UINT8 i;
1008
1009
1010 for (i = 0; i < AslGbl_ExpectedMessagesIndex; ++i)
1011 {
1012 if (!AslGbl_ExpectedMessages[i].MessageReceived)
1013 {
1014 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
1015 AslGbl_ExpectedMessages[i].MessageIdStr);
1016 }
1017 }
1018 }
1019
1020
1021 /*******************************************************************************
1022 *
1023 * FUNCTION: AslExpectException
1024 *
1025 * PARAMETERS: MessageIdString - ID of excepted exception during compile
1026 *
1027 * RETURN: Status
1028 *
1029 * DESCRIPTION: Enter a message ID into the global expected messages table
1030 * If these messages are not raised during the compilation, throw
1031 * an error.
1032 *
1033 ******************************************************************************/
1034
1035 ACPI_STATUS
1036 AslExpectException (
1037 char *MessageIdString)
1038 {
1039 UINT32 MessageId;
1040
1041
1042 /* Convert argument to an integer and validate it */
1043
1044 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1045
1046 if (MessageId > 6999)
1047 {
1048 printf ("\"%s\" is not a valid warning/remark/erro ID\n",
1049 MessageIdString);
1050 return (AE_BAD_PARAMETER);
1051 }
1052
1053 /* Insert value into the global expected message array */
1054
1055 if (AslGbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
1056 {
1057 printf ("Too many messages have been registered as expected (max %d)\n",
1058 ASL_MAX_DISABLED_MESSAGES);
1059 return (AE_LIMIT);
1060 }
1061
1062 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageId = MessageId;
1063 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
1064 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageReceived = FALSE;
1065 AslGbl_ExpectedMessagesIndex++;
1066 return (AE_OK);
1067 }
1068
1069
1070 /*******************************************************************************
1071 *
1072 * FUNCTION: AslDisableException
1073 *
1074 * PARAMETERS: MessageIdString - ID to be disabled
1075 *
1076 * RETURN: Status
1077 *
1078 * DESCRIPTION: Enter a message ID into the global disabled messages table
1079 *
1080 ******************************************************************************/
1081
1082 ACPI_STATUS
1083 AslDisableException (
1084 char *MessageIdString)
1085 {
1086 UINT32 MessageId;
1087
1088
1089 /* Convert argument to an integer and validate it */
1090
1091 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1092
1093 if ((MessageId < 2000) || (MessageId > 6999))
1094 {
1095 printf ("\"%s\" is not a valid warning/remark/error ID\n",
1096 MessageIdString);
1097 return (AE_BAD_PARAMETER);
1098 }
1099
1100 /* Insert value into the global disabled message array */
1101
1102 if (AslGbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
1103 {
1104 printf ("Too many messages have been disabled (max %d)\n",
1105 ASL_MAX_DISABLED_MESSAGES);
1106 return (AE_LIMIT);
1107 }
1108
1109 AslGbl_DisabledMessages[AslGbl_DisabledMessagesIndex] = MessageId;
1110 AslGbl_DisabledMessagesIndex++;
1111 return (AE_OK);
1112 }
1113
1114
1115 /*******************************************************************************
1116 *
1117 * FUNCTION: AslElevateException
1118 *
1119 * PARAMETERS: MessageIdString - ID of excepted exception during compile
1120 *
1121 * RETURN: Status
1122 *
1123 * DESCRIPTION: Enter a message ID into the global elevated exceptions table.
1124 * These messages will be considered as compilation errors.
1125 *
1126 ******************************************************************************/
1127
1128 ACPI_STATUS
1129 AslElevateException (
1130 char *MessageIdString)
1131 {
1132 UINT32 MessageId;
1133
1134
1135 /* Convert argument to an integer and validate it */
1136
1137 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1138
1139 if (MessageId > 6999)
1140 {
1141 printf ("\"%s\" is not a valid warning/remark/erro ID\n",
1142 MessageIdString);
1143 return (AE_BAD_PARAMETER);
1144 }
1145
1146 /* Insert value into the global expected message array */
1147
1148 if (AslGbl_ElevatedMessagesIndex >= ASL_MAX_ELEVATED_MESSAGES)
1149 {
1150 printf ("Too many messages have been registered as elevated (max %d)\n",
1151 ASL_MAX_DISABLED_MESSAGES);
1152 return (AE_LIMIT);
1153 }
1154
1155 AslGbl_ElevatedMessages[AslGbl_ElevatedMessagesIndex] = MessageId;
1156 AslGbl_ElevatedMessagesIndex++;
1157 return (AE_OK);
1158 }
1159
1160 /*******************************************************************************
1161 *
1162 * FUNCTION: AslIsExceptionDisabled
1163 *
1164 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1165 * MessageId - Index into global message buffer
1166 *
1167 * RETURN: TRUE if exception/message should be ignored
1168 *
1169 * DESCRIPTION: Check if the user has specified options such that this
1170 * exception should be ignored
1171 *
1172 ******************************************************************************/
1173
1174 static BOOLEAN
1175 AslIsExceptionExpected (
1176 UINT8 Level,
1177 UINT16 MessageId)
1178 {
1179 UINT32 EncodedMessageId;
1180 UINT32 i;
1181
1182
1183 /* Mark this exception as received */
1184
1185 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1186 for (i = 0; i < AslGbl_ExpectedMessagesIndex; i++)
1187 {
1188 /* Simple implementation via fixed array */
1189
1190 if (EncodedMessageId == AslGbl_ExpectedMessages[i].MessageId)
1191 {
1192 return (AslGbl_ExpectedMessages[i].MessageReceived = TRUE);
1193 }
1194 }
1195
1196 return (FALSE);
1197 }
1198
1199
1200 /*******************************************************************************
1201 *
1202 * FUNCTION: AslIsExceptionDisabled
1203 *
1204 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1205 * MessageId - Index into global message buffer
1206 *
1207 * RETURN: TRUE if exception/message should be ignored
1208 *
1209 * DESCRIPTION: Check if the user has specified options such that this
1210 * exception should be ignored
1211 *
1212 ******************************************************************************/
1213
1214 static BOOLEAN
1215 AslIsExceptionDisabled (
1216 UINT8 Level,
1217 UINT16 MessageId)
1218 {
1219 UINT32 EncodedMessageId;
1220 UINT32 i;
1221
1222
1223 switch (Level)
1224 {
1225 case ASL_WARNING2:
1226 case ASL_WARNING3:
1227
1228 /* Check for global disable via -w1/-w2/-w3 options */
1229
1230 if (Level > AslGbl_WarningLevel)
1231 {
1232 return (TRUE);
1233 }
1234 /* Fall through */
1235
1236 case ASL_WARNING:
1237 case ASL_REMARK:
1238 case ASL_ERROR:
1239 /*
1240 * Ignore this error/warning/remark if it has been disabled by
1241 * the user (-vw option)
1242 */
1243 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1244 for (i = 0; i < AslGbl_DisabledMessagesIndex; i++)
1245 {
1246 /* Simple implementation via fixed array */
1247
1248 if (EncodedMessageId == AslGbl_DisabledMessages[i])
1249 {
1250 return (TRUE);
1251 }
1252 }
1253 break;
1254
1255 default:
1256 break;
1257 }
1258
1259 return (FALSE);
1260 }
1261
1262
1263 /*******************************************************************************
1264 *
1265 * FUNCTION: AslDualParseOpError
1266 *
1267 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1268 * MainMsgId - Index into global message buffer
1269 * MainOp - Parse node where error happened
1270 * MainMsg - Message pertaining to the MainOp
1271 * SubMsgId - Index into global message buffer
1272 * SubOp - Additional parse node for better message
1273 * SubMsg - Message pertaining to SubOp
1274 *
1275 *
1276 * RETURN: None
1277 *
1278 * DESCRIPTION: Main error reporting routine for the ASL compiler for error
1279 * messages that point to multiple parse objects.
1280 *
1281 ******************************************************************************/
1282
1283 void
1284 AslDualParseOpError (
1285 UINT8 Level,
1286 UINT16 MainMsgId,
1287 ACPI_PARSE_OBJECT *MainOp,
1288 char *MainMsg,
1289 UINT16 SubMsgId,
1290 ACPI_PARSE_OBJECT *SubOp,
1291 char *SubMsg)
1292 {
1293 ASL_ERROR_MSG *SubEnode = NULL;
1294
1295
1296 /* Check if user wants to ignore this exception */
1297
1298 if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp)
1299 {
1300 return;
1301 }
1302
1303 if (SubOp)
1304 {
1305 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
1306 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
1307 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
1308 NULL, NULL);
1309 }
1310
1311 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
1312 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
1313 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
1314 NULL, SubEnode);
1315 }
1316
1317
1318 /*******************************************************************************
1319 *
1320 * FUNCTION: AslError
1321 *
1322 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1323 * MessageId - Index into global message buffer
1324 * Op - Parse node where error happened
1325 * ExtraMessage - Additional error message
1326 *
1327 * RETURN: None
1328 *
1329 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
1330 * except the parser.)
1331 *
1332 ******************************************************************************/
1333
1334 void
1335 AslError (
1336 UINT8 Level,
1337 UINT16 MessageId,
1338 ACPI_PARSE_OBJECT *Op,
1339 char *ExtraMessage)
1340 {
1341 if (Op)
1342 {
1343 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
1344 Op->Asl.LogicalLineNumber,
1345 Op->Asl.LogicalByteOffset,
1346 Op->Asl.Column,
1347 Op->Asl.Filename, ExtraMessage);
1348 }
1349 else
1350 {
1351 AslCommonError (Level, MessageId, 0,
1352 0, 0, 0, NULL, ExtraMessage);
1353 }
1354 }
1355
1356
1357 /*******************************************************************************
1358 *
1359 * FUNCTION: AslCoreSubsystemError
1360 *
1361 * PARAMETERS: Op - Parse node where error happened
1362 * Status - The ACPICA Exception
1363 * ExtraMessage - Additional error message
1364 * Abort - TRUE -> Abort compilation
1365 *
1366 * RETURN: None
1367 *
1368 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
1369 * core subsystem.
1370 *
1371 ******************************************************************************/
1372
1373 void
1374 AslCoreSubsystemError (
1375 ACPI_PARSE_OBJECT *Op,
1376 ACPI_STATUS Status,
1377 char *ExtraMessage,
1378 BOOLEAN Abort)
1379 {
1380
1381 sprintf (AslGbl_MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
1382
1383 if (Op)
1384 {
1385 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1386 Op->Asl.LineNumber,
1387 Op->Asl.LogicalLineNumber,
1388 Op->Asl.LogicalByteOffset,
1389 Op->Asl.Column,
1390 Op->Asl.Filename, AslGbl_MsgBuffer);
1391 }
1392 else
1393 {
1394 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1395 0, 0, 0, 0, NULL, AslGbl_MsgBuffer);
1396 }
1397
1398 if (Abort)
1399 {
1400 AslAbort ();
1401 }
1402 }
1403
1404
1405 /*******************************************************************************
1406 *
1407 * FUNCTION: AslCompilererror
1408 *
1409 * PARAMETERS: CompilerMessage - Error message from the parser
1410 *
1411 * RETURN: Status (0 for now)
1412 *
1413 * DESCRIPTION: Report an error situation discovered in a production
1414 * NOTE: don't change the name of this function, it is called
1415 * from the auto-generated parser.
1416 *
1417 ******************************************************************************/
1418
1419 int
1420 AslCompilererror (
1421 const char *CompilerMessage)
1422 {
1423
1424 AslGbl_SyntaxError++;
1425
1426 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
1427 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
1428 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename,
1429 ACPI_CAST_PTR (char, CompilerMessage));
1430
1431 return (0);
1432 }
1433