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