aslerror.c revision 1.10 1 /******************************************************************************
2 *
3 * Module Name: aslerror - Error handling and statistics
4 *
5 *****************************************************************************/
6
7 /*
8 * Copyright (C) 2000 - 2018, 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 /* Check if user wants to ignore this exception */
817
818 if (AslIsExceptionIgnored (Level, MessageId))
819 {
820 return;
821 }
822
823 AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
824 LogicalByteOffset, Column, Filename, ExtraMessage,
825 NULL, NULL);
826 }
827
828
829 /*******************************************************************************
830 *
831 * FUNCTION: AslLogNewError
832 *
833 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
834 * MessageId - Index into global message buffer
835 * CurrentLineNumber - Actual file line number
836 * LogicalLineNumber - Cumulative line number
837 * LogicalByteOffset - Byte offset in source file
838 * Column - Column in current line
839 * Filename - source filename
840 * Message - additional error message
841 * SourceLine - Actual line of source code
842 * SubError - Sub-error associated with this error
843 *
844 * RETURN: None
845 *
846 * DESCRIPTION: Create a new error node and add it to the error log
847 *
848 ******************************************************************************/
849 static void
850 AslLogNewError (
851 UINT8 Level,
852 UINT16 MessageId,
853 UINT32 LineNumber,
854 UINT32 LogicalLineNumber,
855 UINT32 LogicalByteOffset,
856 UINT32 Column,
857 char *Filename,
858 char *Message,
859 char *SourceLine,
860 ASL_ERROR_MSG *SubError)
861 {
862 ASL_ERROR_MSG *Enode = NULL;
863
864
865 AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber,
866 LogicalByteOffset, Column, Filename, Message, SourceLine,
867 SubError);
868
869 /* Add the new node to the error node list */
870
871 AeAddToErrorLog (Enode);
872
873 if (Gbl_DebugFlag)
874 {
875 /* stderr is a file, send error to it immediately */
876
877 AePrintException (ASL_FILE_STDERR, Enode, NULL);
878 }
879
880 Gbl_ExceptionCount[Level]++;
881 if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
882 {
883 printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
884
885 Gbl_SourceLine = 0;
886 Gbl_NextError = Gbl_ErrorLog;
887 CmCleanupAndExit ();
888 exit(1);
889 }
890
891 return;
892 }
893
894 /*******************************************************************************
895 *
896 * FUNCTION: AslIsExceptionIgnored
897 *
898 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
899 * MessageId - Index into global message buffer
900 *
901 * RETURN: BOOLEAN
902 *
903 * DESCRIPTION: Check if a particular exception is ignored. In this case it
904 * means that the exception is (expected or disabled.
905 *
906 ******************************************************************************/
907
908 BOOLEAN
909 AslIsExceptionIgnored (
910 UINT8 Level,
911 UINT16 MessageId)
912 {
913 BOOLEAN ExceptionIgnored;
914
915
916 /* Note: this allows exception to be disabled and expected */
917
918 ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
919 ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId);
920
921 return (Gbl_AllExceptionsDisabled || ExceptionIgnored);
922 }
923
924
925 /*******************************************************************************
926 *
927 * FUNCTION: AslCheckExpectException
928 *
929 * PARAMETERS: none
930 *
931 * RETURN: none
932 *
933 * DESCRIPTION: Check the global expected messages table and raise an error
934 * for each message that has not been received.
935 *
936 ******************************************************************************/
937
938 void
939 AslCheckExpectedExceptions (
940 void)
941 {
942 UINT8 i;
943
944
945 for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i)
946 {
947 if (!Gbl_ExpectedMessages[i].MessageReceived)
948 {
949 AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
950 Gbl_ExpectedMessages[i].MessageIdStr);
951 }
952 }
953 }
954
955
956 /*******************************************************************************
957 *
958 * FUNCTION: AslExpectException
959 *
960 * PARAMETERS: MessageIdString - ID of excepted exception during compile
961 *
962 * RETURN: Status
963 *
964 * DESCRIPTION: Enter a message ID into the global expected messages table
965 * If these messages are not raised during the compilation, throw
966 * an error.
967 *
968 ******************************************************************************/
969
970 ACPI_STATUS
971 AslExpectException (
972 char *MessageIdString)
973 {
974 UINT32 MessageId;
975
976
977 /* Convert argument to an integer and validate it */
978
979 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
980
981 if (MessageId > 6999)
982 {
983 printf ("\"%s\" is not a valid warning/remark/erro ID\n",
984 MessageIdString);
985 return (AE_BAD_PARAMETER);
986 }
987
988 /* Insert value into the global expected message array */
989
990 if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
991 {
992 printf ("Too many messages have been registered as expected (max %u)\n",
993 ASL_MAX_DISABLED_MESSAGES);
994 return (AE_LIMIT);
995 }
996
997 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId;
998 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
999 Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE;
1000 Gbl_ExpectedMessagesIndex++;
1001 return (AE_OK);
1002 }
1003
1004
1005 /*******************************************************************************
1006 *
1007 * FUNCTION: AslDisableException
1008 *
1009 * PARAMETERS: MessageIdString - ID to be disabled
1010 *
1011 * RETURN: Status
1012 *
1013 * DESCRIPTION: Enter a message ID into the global disabled messages table
1014 *
1015 ******************************************************************************/
1016
1017 ACPI_STATUS
1018 AslDisableException (
1019 char *MessageIdString)
1020 {
1021 UINT32 MessageId;
1022
1023
1024 /* Convert argument to an integer and validate it */
1025
1026 MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
1027
1028 if ((MessageId < 2000) || (MessageId > 6999))
1029 {
1030 printf ("\"%s\" is not a valid warning/remark/error ID\n",
1031 MessageIdString);
1032 return (AE_BAD_PARAMETER);
1033 }
1034
1035 /* Insert value into the global disabled message array */
1036
1037 if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
1038 {
1039 printf ("Too many messages have been disabled (max %u)\n",
1040 ASL_MAX_DISABLED_MESSAGES);
1041 return (AE_LIMIT);
1042 }
1043
1044 Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
1045 Gbl_DisabledMessagesIndex++;
1046 return (AE_OK);
1047 }
1048
1049
1050 /*******************************************************************************
1051 *
1052 * FUNCTION: AslIsExceptionDisabled
1053 *
1054 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1055 * MessageId - Index into global message buffer
1056 *
1057 * RETURN: TRUE if exception/message should be ignored
1058 *
1059 * DESCRIPTION: Check if the user has specified options such that this
1060 * exception should be ignored
1061 *
1062 ******************************************************************************/
1063
1064 static BOOLEAN
1065 AslIsExceptionExpected (
1066 UINT8 Level,
1067 UINT16 MessageId)
1068 {
1069 UINT32 EncodedMessageId;
1070 UINT32 i;
1071
1072
1073 /* Mark this exception as received */
1074
1075 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1076 for (i = 0; i < Gbl_ExpectedMessagesIndex; i++)
1077 {
1078 /* Simple implementation via fixed array */
1079
1080 if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId)
1081 {
1082 return (Gbl_ExpectedMessages[i].MessageReceived = TRUE);
1083 }
1084 }
1085
1086 return (FALSE);
1087 }
1088
1089
1090 /*******************************************************************************
1091 *
1092 * FUNCTION: AslIsExceptionDisabled
1093 *
1094 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1095 * MessageId - Index into global message buffer
1096 *
1097 * RETURN: TRUE if exception/message should be ignored
1098 *
1099 * DESCRIPTION: Check if the user has specified options such that this
1100 * exception should be ignored
1101 *
1102 ******************************************************************************/
1103
1104 static BOOLEAN
1105 AslIsExceptionDisabled (
1106 UINT8 Level,
1107 UINT16 MessageId)
1108 {
1109 UINT32 EncodedMessageId;
1110 UINT32 i;
1111
1112
1113 switch (Level)
1114 {
1115 case ASL_WARNING2:
1116 case ASL_WARNING3:
1117
1118 /* Check for global disable via -w1/-w2/-w3 options */
1119
1120 if (Level > Gbl_WarningLevel)
1121 {
1122 return (TRUE);
1123 }
1124 /* Fall through */
1125
1126 case ASL_WARNING:
1127 case ASL_REMARK:
1128 case ASL_ERROR:
1129 /*
1130 * Ignore this error/warning/remark if it has been disabled by
1131 * the user (-vw option)
1132 */
1133 EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
1134 for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
1135 {
1136 /* Simple implementation via fixed array */
1137
1138 if (EncodedMessageId == Gbl_DisabledMessages[i])
1139 {
1140 return (TRUE);
1141 }
1142 }
1143 break;
1144
1145 default:
1146 break;
1147 }
1148
1149 return (FALSE);
1150 }
1151
1152
1153 /*******************************************************************************
1154 *
1155 * FUNCTION: AslDualParseOpError
1156 *
1157 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1158 * MainMsgId - Index into global message buffer
1159 * MainOp - Parse node where error happened
1160 * MainMsg - Message pertaining to the MainOp
1161 * SubMsgId - Index into global message buffer
1162 * SubOp - Additional parse node for better message
1163 * SubMsg - Message pertainint to SubOp
1164 *
1165 *
1166 * RETURN: None
1167 *
1168 * DESCRIPTION: Main error reporting routine for the ASL compiler for error
1169 * messages that point to multiple parse objects.
1170 *
1171 ******************************************************************************/
1172
1173 void
1174 AslDualParseOpError (
1175 UINT8 Level,
1176 UINT16 MainMsgId,
1177 ACPI_PARSE_OBJECT *MainOp,
1178 char *MainMsg,
1179 UINT16 SubMsgId,
1180 ACPI_PARSE_OBJECT *SubOp,
1181 char *SubMsg)
1182 {
1183 ASL_ERROR_MSG *SubEnode = NULL;
1184
1185
1186 /* Check if user wants to ignore this exception */
1187
1188 if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp)
1189 {
1190 return;
1191 }
1192
1193 if (SubOp)
1194 {
1195 AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
1196 SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
1197 SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
1198 NULL, NULL);
1199 }
1200
1201 AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
1202 MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
1203 MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
1204 NULL, SubEnode);
1205 }
1206
1207
1208 /*******************************************************************************
1209 *
1210 * FUNCTION: AslError
1211 *
1212 * PARAMETERS: Level - Seriousness (Warning/error, etc.)
1213 * MessageId - Index into global message buffer
1214 * Op - Parse node where error happened
1215 * ExtraMessage - additional error message
1216 *
1217 * RETURN: None
1218 *
1219 * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
1220 * except the parser.)
1221 *
1222 ******************************************************************************/
1223
1224 void
1225 AslError (
1226 UINT8 Level,
1227 UINT16 MessageId,
1228 ACPI_PARSE_OBJECT *Op,
1229 char *ExtraMessage)
1230 {
1231 if (Op)
1232 {
1233 AslCommonError (Level, MessageId, Op->Asl.LineNumber,
1234 Op->Asl.LogicalLineNumber,
1235 Op->Asl.LogicalByteOffset,
1236 Op->Asl.Column,
1237 Op->Asl.Filename, ExtraMessage);
1238 }
1239 else
1240 {
1241 AslCommonError (Level, MessageId, 0,
1242 0, 0, 0, NULL, ExtraMessage);
1243 }
1244 }
1245
1246
1247 /*******************************************************************************
1248 *
1249 * FUNCTION: AslCoreSubsystemError
1250 *
1251 * PARAMETERS: Op - Parse node where error happened
1252 * Status - The ACPICA Exception
1253 * ExtraMessage - additional error message
1254 * Abort - TRUE -> Abort compilation
1255 *
1256 * RETURN: None
1257 *
1258 * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
1259 * core subsystem.
1260 *
1261 ******************************************************************************/
1262
1263 void
1264 AslCoreSubsystemError (
1265 ACPI_PARSE_OBJECT *Op,
1266 ACPI_STATUS Status,
1267 char *ExtraMessage,
1268 BOOLEAN Abort)
1269 {
1270
1271 snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage);
1272
1273 if (Op)
1274 {
1275 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1276 Op->Asl.LineNumber,
1277 Op->Asl.LogicalLineNumber,
1278 Op->Asl.LogicalByteOffset,
1279 Op->Asl.Column,
1280 Op->Asl.Filename, MsgBuffer);
1281 }
1282 else
1283 {
1284 AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1285 0, 0, 0, 0, NULL, MsgBuffer);
1286 }
1287
1288 if (Abort)
1289 {
1290 AslAbort ();
1291 }
1292 }
1293
1294
1295 /*******************************************************************************
1296 *
1297 * FUNCTION: AslCompilererror
1298 *
1299 * PARAMETERS: CompilerMessage - Error message from the parser
1300 *
1301 * RETURN: Status (0 for now)
1302 *
1303 * DESCRIPTION: Report an error situation discovered in a production
1304 * NOTE: don't change the name of this function, it is called
1305 * from the auto-generated parser.
1306 *
1307 ******************************************************************************/
1308
1309 int
1310 AslCompilererror (
1311 const char *CompilerMessage)
1312 {
1313
1314 Gbl_SyntaxError++;
1315
1316 AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
1317 Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
1318 Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
1319 ACPI_CAST_PTR (char, CompilerMessage));
1320
1321 return (0);
1322 }
1323