aslerror.c revision 1.1.1.20 1 /******************************************************************************
2 *
3 * Module Name: aslerror - Error handling and statistics
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2022, 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 MERCHANTABILITY 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 Enode->SourceFilename =
784 FileNode->Files[ASL_FILE_SOURCE_OUTPUT].Filename;
785 }
786 }
787
788
789 /*******************************************************************************
790 *
791 * FUNCTION: AslCommonError2
792 *
793 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
794 * MessageId - Index into global message buffer
795 * LineNumber - Actual file line number
796 * Column - Column in current line
797 * SourceLine - Actual source code line
798 * Filename - Source filename
799 * ExtraMessage - Additional error message
800 *
801 * RETURN: None
802 *
803 * DESCRIPTION: Create a new error node and add it to the error log
804 *
805 ******************************************************************************/
806
807 void
808 AslCommonError2 (
809 UINT8 Level,
810 UINT16 MessageId,
811 UINT32 LineNumber,
812 UINT32 Column,
813 char *SourceLine,
814 char *Filename,
815 char *ExtraMessage)
816 {
817 AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column,
818 Filename, ExtraMessage, SourceLine, NULL);
819 }
820
821
822 /*******************************************************************************
823 *
824 * FUNCTION: AslCommonError
825 *
826 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
827 * MessageId - Index into global message buffer
828 * CurrentLineNumber - Actual file line number
829 * LogicalLineNumber - Cumulative line number
830 * LogicalByteOffset - Byte offset in source file
831 * Column - Column in current line
832 * Filename - Source filename
833 * ExtraMessage - Additional error message
834 *
835 * RETURN: None
836 *
837 * DESCRIPTION: Create a new error node and add it to the error log
838 *
839 ******************************************************************************/
840
841 void
842 AslCommonError (
843 UINT8 Level,
844 UINT16 MessageId,
845 UINT32 CurrentLineNumber,
846 UINT32 LogicalLineNumber,
847 UINT32 LogicalByteOffset,
848 UINT32 Column,
849 char *Filename,
850 char *ExtraMessage)
851 {
852 /* Check if user wants to ignore this exception */
853
854 if (AslIsExceptionIgnored (Filename, LogicalLineNumber, Level, MessageId))
855 {
856 return;
857 }
858
859 AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
860 LogicalByteOffset, Column, Filename, ExtraMessage,
861 NULL, NULL);
862 }
863
864
865 /*******************************************************************************
866 *
867 * FUNCTION: AslLogNewError
868 *
869 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
870 * MessageId - Index into global message buffer
871 * CurrentLineNumber - Actual file line number
872 * LogicalLineNumber - Cumulative line number
873 * LogicalByteOffset - Byte offset in source file
874 * Column - Column in current line
875 * Filename - Source filename
876 * Message - Additional error message
877 * SourceLine - Actual line of source code
878 * SubError - Sub-error associated with this error
879 *
880 * RETURN: None
881 *
882 * DESCRIPTION: Create a new error node and add it to the error log
883 *
884 ******************************************************************************/
885 static void
886 AslLogNewError (
887 UINT8 Level,
888 UINT16 MessageId,
889 UINT32 LineNumber,
890 UINT32 LogicalLineNumber,
891 UINT32 LogicalByteOffset,
892 UINT32 Column,
893 char *Filename,
894 char *Message,
895 char *SourceLine,
896 ASL_ERROR_MSG *SubError)
897 {
898 ASL_ERROR_MSG *Enode = NULL;
899 UINT8 ModifiedLevel = GetModifiedLevel (Level, MessageId);
900
901
902 AslInitEnode (&Enode, ModifiedLevel, MessageId, LineNumber,
903 LogicalLineNumber, LogicalByteOffset, Column, Filename, Message,
904 SourceLine, SubError);
905
906 /* Add the new node to the error node list */
907
908 AeAddToErrorLog (Enode);
909
910 if (AslGbl_DebugFlag)
911 {
912 /* stderr is a file, send error to it immediately */
913
914 AePrintException (ASL_FILE_STDERR, Enode, NULL);
915 }
916
917 AslGbl_ExceptionCount[ModifiedLevel]++;
918 if (!AslGbl_IgnoreErrors && AslGbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
919 {
920 printf ("\nMaximum error count (%u) exceeded (aslerror.c)\n", ASL_MAX_ERROR_COUNT);
921
922 AslGbl_SourceLine = 0;
923 AslGbl_NextError = AslGbl_ErrorLog;
924 CmCleanupAndExit ();
925 exit(1);
926 }
927
928 AslGbl_ExceptionCount[ASL_ERROR] = 0;
929 return;
930 }
931
932
933 /*******************************************************************************
934 *
935 * FUNCTION: GetModifiedLevel
936 *
937 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
938 * MessageId - Index into global message buffer
939 *
940 * RETURN: UINT8 - Modified level
941 *
942 * DESCRIPTION: Get the modified level of exception codes that are reported as
943 * errors from the -ww option.
944 *
945 ******************************************************************************/
946
947 static UINT8
948 GetModifiedLevel (
949 UINT8 Level,
950 UINT16 MessageId)
951 {
952 UINT32 i;
953 UINT16 ExceptionCode;
954
955
956 ExceptionCode = AeBuildFullExceptionCode (Level, MessageId);
957
958 for (i = 0; i < AslGbl_ElevatedMessagesIndex; i++)
959 {
960 if (ExceptionCode == AslGbl_ElevatedMessages[i])
961 {
962 return (ASL_ERROR);
963 }
964 }
965
966 return (Level);
967 }
968
969
970 /*******************************************************************************
971 *
972 * FUNCTION: AslIsExceptionIgnored
973 *
974 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
975 * MessageId - Index into global message buffer
976 *
977 * RETURN: BOOLEAN
978 *
979 * DESCRIPTION: Check if a particular exception is ignored. In this case it
980 * means that the exception is (expected or disabled.
981 *
982 ******************************************************************************/
983
984 BOOLEAN
985 AslIsExceptionIgnored (
986 char *Filename,
987 UINT32 LineNumber,
988 UINT8 Level,
989 UINT16 MessageId)
990 {
991 BOOLEAN ExceptionIgnored;
992
993
994 /* Note: this allows exception to be disabled and expected */
995
996 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
997 ExceptionIgnored |=
998 AslIsExceptionExpected (Filename, LineNumber, Level, MessageId);
999
1000 return (AslGbl_AllExceptionsDisabled || ExceptionIgnored);
1001 }
1002
1003
1004 /*******************************************************************************
1005 *
1006 * FUNCTION: AslCheckExpectedException
1007 *
1008 * PARAMETERS: none
1009 *
1010 * RETURN: none
1011 *
1012 * DESCRIPTION: Check the global expected messages table and raise an error
1013 * for each message that has not been received.
1014 *
1015 ******************************************************************************/
1016
1017 void
1018 AslCheckExpectedExceptions (
1019 void)
1020 {
1021 UINT32 i;
1022 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList;
1023 ASL_LOCATION_NODE *LocationNode;
1024
1025
1026 for (i = 0; i < AslGbl_ExpectedMessagesIndex; ++i)
1027 {
1028 if (!AslGbl_ExpectedMessages[i].MessageReceived)
1029 {
1030 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
1031 AslGbl_ExpectedMessages[i].MessageIdStr);
1032 }
1033 }
1034
1035 while (Current)
1036 {
1037 LocationNode = Current->LocationList;
1038
1039 while (LocationNode)
1040 {
1041 if (!LocationNode->MessageReceived)
1042 {
1043 AslCommonError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED,
1044 LocationNode->LineNumber, LocationNode->LineNumber,
1045 LocationNode->LogicalByteOffset, LocationNode->Column,
1046 LocationNode->Filename, Current->MessageIdStr);
1047 }
1048
1049 LocationNode = LocationNode->Next;
1050 }
1051
1052 Current = Current->Next;
1053 }
1054 }
1055
1056
1057 /*******************************************************************************
1058 *
1059 * FUNCTION: AslLogExpectedException
1060 *
1061 * PARAMETERS: MessageIdString - ID of excepted exception during compile
1062 *
1063 * RETURN: Status
1064 *
1065 * DESCRIPTION: Enter a message ID into the global expected messages table
1066 * If these messages are not raised during the compilation, throw
1067 * an error.
1068 *
1069 ******************************************************************************/
1070
1071 ACPI_STATUS
1072 AslLogExpectedException (
1073 char *MessageIdString)
1074 {
1075 UINT32 MessageId;
1076
1077
1078 /* Convert argument to an integer and validate it */
1079
1080 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1081
1082 if (MessageId > 6999)
1083 {
1084 printf ("\"%s\" is not a valid warning/remark/error ID\n",
1085 MessageIdString);
1086 return (AE_BAD_PARAMETER);
1087 }
1088
1089 /* Insert value into the global expected message array */
1090
1091 if (AslGbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
1092 {
1093 printf ("Too many messages have been registered as expected (max %d)\n",
1094 ASL_MAX_DISABLED_MESSAGES);
1095 return (AE_LIMIT);
1096 }
1097
1098 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageId = MessageId;
1099 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
1100 AslGbl_ExpectedMessages[AslGbl_ExpectedMessagesIndex].MessageReceived = FALSE;
1101 AslGbl_ExpectedMessagesIndex++;
1102 return (AE_OK);
1103 }
1104
1105
1106 /*******************************************************************************
1107 *
1108 * FUNCTION: AslLogExpectedExceptionByLine
1109 *
1110 * PARAMETERS: MessageIdString - ID of excepted exception during compile
1111 *
1112 * RETURN: Status
1113 *
1114 * DESCRIPTION: Enter a message ID into the global expected messages table
1115 * based on file and line number. If these messages are not raised
1116 * during the compilation, throw an error.
1117 *
1118 ******************************************************************************/
1119
1120 void
1121 AslLogExpectedExceptionByLine (
1122 char *MessageIdString)
1123 {
1124 ASL_LOCATION_NODE *NewErrorLocationNode;
1125 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList;
1126 UINT32 MessageId;
1127
1128
1129 NewErrorLocationNode = UtLocalCalloc (sizeof (ASL_LOCATION_NODE));
1130
1131 NewErrorLocationNode->LineNumber = AslGbl_CurrentLineNumber;
1132 NewErrorLocationNode->Filename = AslGbl_Files[ASL_FILE_INPUT].Filename;
1133 NewErrorLocationNode->LogicalByteOffset = AslGbl_CurrentLineOffset;
1134 NewErrorLocationNode->Column = AslGbl_CurrentColumn;
1135
1136 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1137
1138 /* search the existing list for a matching message ID */
1139
1140 while (Current && Current->MessageId != MessageId )
1141 {
1142 Current = Current->Next;
1143 }
1144 if (!Current)
1145 {
1146 /* ID was not found, create a new node for this message ID */
1147
1148 Current = UtLocalCalloc (sizeof (ASL_EXPECTED_MSG_NODE));
1149
1150 Current->Next = AslGbl_ExpectedErrorCodeList;
1151 Current->MessageIdStr = MessageIdString;
1152 Current->MessageId = MessageId;
1153 AslGbl_ExpectedErrorCodeList = Current;
1154 }
1155
1156 NewErrorLocationNode->Next = Current->LocationList;
1157 Current->LocationList = NewErrorLocationNode;
1158 }
1159
1160
1161 /*******************************************************************************
1162 *
1163 * FUNCTION: AslDisableException
1164 *
1165 * PARAMETERS: MessageIdString - ID to be disabled
1166 *
1167 * RETURN: Status
1168 *
1169 * DESCRIPTION: Enter a message ID into the global disabled messages table
1170 *
1171 ******************************************************************************/
1172
1173 ACPI_STATUS
1174 AslDisableException (
1175 char *MessageIdString)
1176 {
1177 UINT32 MessageId;
1178
1179
1180 /* Convert argument to an integer and validate it */
1181
1182 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1183
1184 if ((MessageId < 2000) || (MessageId > 6999))
1185 {
1186 printf ("\"%s\" is not a valid warning/remark/error ID\n",
1187 MessageIdString);
1188 return (AE_BAD_PARAMETER);
1189 }
1190
1191 /* Insert value into the global disabled message array */
1192
1193 if (AslGbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
1194 {
1195 printf ("Too many messages have been disabled (max %d)\n",
1196 ASL_MAX_DISABLED_MESSAGES);
1197 return (AE_LIMIT);
1198 }
1199
1200 AslGbl_DisabledMessages[AslGbl_DisabledMessagesIndex] = MessageId;
1201 AslGbl_DisabledMessagesIndex++;
1202 return (AE_OK);
1203 }
1204
1205
1206 /*******************************************************************************
1207 *
1208 * FUNCTION: AslElevateException
1209 *
1210 * PARAMETERS: MessageIdString - ID of excepted exception during compile
1211 *
1212 * RETURN: Status
1213 *
1214 * DESCRIPTION: Enter a message ID into the global elevated exceptions table.
1215 * These messages will be considered as compilation errors.
1216 *
1217 ******************************************************************************/
1218
1219 ACPI_STATUS
1220 AslElevateException (
1221 char *MessageIdString)
1222 {
1223 UINT32 MessageId;
1224
1225
1226 /* Convert argument to an integer and validate it */
1227
1228 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1229
1230 if (MessageId > 6999)
1231 {
1232 printf ("\"%s\" is not a valid warning/remark/error ID\n",
1233 MessageIdString);
1234 return (AE_BAD_PARAMETER);
1235 }
1236
1237 /* Insert value into the global expected message array */
1238
1239 if (AslGbl_ElevatedMessagesIndex >= ASL_MAX_ELEVATED_MESSAGES)
1240 {
1241 printf ("Too many messages have been registered as elevated (max %d)\n",
1242 ASL_MAX_DISABLED_MESSAGES);
1243 return (AE_LIMIT);
1244 }
1245
1246 AslGbl_ElevatedMessages[AslGbl_ElevatedMessagesIndex] = MessageId;
1247 AslGbl_ElevatedMessagesIndex++;
1248 return (AE_OK);
1249 }
1250
1251
1252 /*******************************************************************************
1253 *
1254 * FUNCTION: AslIsExceptionDisabled
1255 *
1256 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1257 * MessageId - Index into global message buffer
1258 *
1259 * RETURN: TRUE if exception/message should be ignored
1260 *
1261 * DESCRIPTION: Check if the user has specified options such that this
1262 * exception should be ignored
1263 *
1264 ******************************************************************************/
1265
1266 static BOOLEAN
1267 AslIsExceptionExpected (
1268 char *Filename,
1269 UINT32 LineNumber,
1270 UINT8 Level,
1271 UINT16 MessageId)
1272 {
1273 ASL_EXPECTED_MSG_NODE *Current = AslGbl_ExpectedErrorCodeList;
1274 ASL_LOCATION_NODE *CurrentErrorLocation;
1275 UINT32 EncodedMessageId;
1276 UINT32 i;
1277
1278
1279 /* Mark this exception as received */
1280
1281 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1282 for (i = 0; i < AslGbl_ExpectedMessagesIndex; i++)
1283 {
1284 /* Simple implementation via fixed array */
1285
1286 if (EncodedMessageId == AslGbl_ExpectedMessages[i].MessageId)
1287 {
1288 return (AslGbl_ExpectedMessages[i].MessageReceived = TRUE);
1289 }
1290 }
1291
1292 while (Current && Current->MessageId != EncodedMessageId)
1293 {
1294 Current = Current->Next;
1295 }
1296 if (!Current)
1297 {
1298 return (FALSE);
1299 }
1300
1301 CurrentErrorLocation = Current->LocationList;
1302
1303 while (CurrentErrorLocation)
1304 {
1305 if (!strcmp (CurrentErrorLocation->Filename, Filename) &&
1306 CurrentErrorLocation->LineNumber == LineNumber)
1307 {
1308 return (CurrentErrorLocation->MessageReceived = TRUE);
1309 }
1310
1311 CurrentErrorLocation = CurrentErrorLocation->Next;
1312 }
1313
1314 return (FALSE);
1315 }
1316
1317
1318 /*******************************************************************************
1319 *
1320 * FUNCTION: AslIsExceptionDisabled
1321 *
1322 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1323 * MessageId - Index into global message buffer
1324 *
1325 * RETURN: TRUE if exception/message should be ignored
1326 *
1327 * DESCRIPTION: Check if the user has specified options such that this
1328 * exception should be ignored
1329 *
1330 ******************************************************************************/
1331
1332 static BOOLEAN
1333 AslIsExceptionDisabled (
1334 UINT8 Level,
1335 UINT16 MessageId)
1336 {
1337 UINT32 EncodedMessageId;
1338 UINT32 i;
1339
1340
1341 switch (Level)
1342 {
1343 case ASL_WARNING2:
1344 case ASL_WARNING3:
1345
1346 /* Check for global disable via -w1/-w2/-w3 options */
1347
1348 if (Level > AslGbl_WarningLevel)
1349 {
1350 return (TRUE);
1351 }
1352 ACPI_FALLTHROUGH;
1353
1354 case ASL_WARNING:
1355 case ASL_REMARK:
1356 case ASL_ERROR:
1357 /*
1358 * Ignore this error/warning/remark if it has been disabled by
1359 * the user (-vw option)
1360 */
1361 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1362 for (i = 0; i < AslGbl_DisabledMessagesIndex; i++)
1363 {
1364 /* Simple implementation via fixed array */
1365
1366 if (EncodedMessageId == AslGbl_DisabledMessages[i])
1367 {
1368 return (TRUE);
1369 }
1370 }
1371 break;
1372
1373 default:
1374 break;
1375 }
1376
1377 return (FALSE);
1378 }
1379
1380
1381 /*******************************************************************************
1382 *
1383 * FUNCTION: AslDualParseOpError
1384 *
1385 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1386 * MainMsgId - Index into global message buffer
1387 * MainOp - Parse node where error happened
1388 * MainMsg - Message pertaining to the MainOp
1389 * SubMsgId - Index into global message buffer
1390 * SubOp - Additional parse node for better message
1391 * SubMsg - Message pertaining to SubOp
1392 *
1393 *
1394 * RETURN: None
1395 *
1396 * DESCRIPTION: Main error reporting routine for the ASL compiler for error
1397 * messages that point to multiple parse objects.
1398 *
1399 ******************************************************************************/
1400
1401 void
1402 AslDualParseOpError (
1403 UINT8 Level,
1404 UINT16 MainMsgId,
1405 ACPI_PARSE_OBJECT *MainOp,
1406 char *MainMsg,
1407 UINT16 SubMsgId,
1408 ACPI_PARSE_OBJECT *SubOp,
1409 char *SubMsg)
1410 {
1411 ASL_ERROR_MSG *SubEnode = NULL;
1412
1413
1414 /* Check if user wants to ignore this exception */
1415
1416 if (!MainOp || AslIsExceptionIgnored (MainOp->Asl.Filename,
1417 MainOp->Asl.LogicalLineNumber, Level, MainMsgId))
1418 {
1419 return;
1420 }
1421
1422 if (SubOp)
1423 {
1424 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
1425 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
1426 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
1427 NULL, NULL);
1428 }
1429
1430 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
1431 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
1432 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
1433 NULL, SubEnode);
1434 }
1435
1436
1437 /*******************************************************************************
1438 *
1439 * FUNCTION: AslError
1440 *
1441 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1442 * MessageId - Index into global message buffer
1443 * Op - Parse node where error happened
1444 * ExtraMessage - Additional error message
1445 *
1446 * RETURN: None
1447 *
1448 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
1449 * except the parser.)
1450 *
1451 ******************************************************************************/
1452
1453 void
1454 AslError (
1455 UINT8 Level,
1456 UINT16 MessageId,
1457 ACPI_PARSE_OBJECT *Op,
1458 char *ExtraMessage)
1459 {
1460 if (Op)
1461 {
1462 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
1463 Op->Asl.LogicalLineNumber,
1464 Op->Asl.LogicalByteOffset,
1465 Op->Asl.Column,
1466 Op->Asl.Filename, ExtraMessage);
1467 }
1468 else
1469 {
1470 AslCommonError (Level, MessageId, 0,
1471 0, 0, 0, NULL, ExtraMessage);
1472 }
1473 }
1474
1475
1476 /*******************************************************************************
1477 *
1478 * FUNCTION: AslCoreSubsystemError
1479 *
1480 * PARAMETERS: Op - Parse node where error happened
1481 * Status - The ACPICA Exception
1482 * ExtraMessage - Additional error message
1483 * Abort - TRUE -> Abort compilation
1484 *
1485 * RETURN: None
1486 *
1487 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
1488 * core subsystem.
1489 *
1490 ******************************************************************************/
1491
1492 void
1493 AslCoreSubsystemError (
1494 ACPI_PARSE_OBJECT *Op,
1495 ACPI_STATUS Status,
1496 char *ExtraMessage,
1497 BOOLEAN Abort)
1498 {
1499
1500 sprintf (AslGbl_MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
1501
1502 if (Op)
1503 {
1504 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1505 Op->Asl.LineNumber,
1506 Op->Asl.LogicalLineNumber,
1507 Op->Asl.LogicalByteOffset,
1508 Op->Asl.Column,
1509 Op->Asl.Filename, AslGbl_MsgBuffer);
1510 }
1511 else
1512 {
1513 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1514 0, 0, 0, 0, NULL, AslGbl_MsgBuffer);
1515 }
1516
1517 if (Abort)
1518 {
1519 AslAbort ();
1520 }
1521 }
1522
1523
1524 /*******************************************************************************
1525 *
1526 * FUNCTION: AslCompilererror
1527 *
1528 * PARAMETERS: CompilerMessage - Error message from the parser
1529 *
1530 * RETURN: Status (0 for now)
1531 *
1532 * DESCRIPTION: Report an error situation discovered in a production
1533 * NOTE: don't change the name of this function, it is called
1534 * from the auto-generated parser.
1535 *
1536 ******************************************************************************/
1537
1538 int
1539 AslCompilererror (
1540 const char *CompilerMessage)
1541 {
1542
1543 AslGbl_SyntaxError++;
1544
1545 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, AslGbl_CurrentLineNumber,
1546 AslGbl_LogicalLineNumber, AslGbl_CurrentLineOffset,
1547 AslGbl_CurrentColumn, AslGbl_Files[ASL_FILE_INPUT].Filename,
1548 ACPI_CAST_PTR (char, CompilerMessage));
1549
1550 return (0);
1551 }
1552