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