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