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