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