1 /******************************************************************************
2  *
3  * Module Name: aslerror - Error handling and statistics
4  *
5  *****************************************************************************/
6 
7 /******************************************************************************
8  *
9  * 1. Copyright Notice
10  *
11  * Some or all of this work - Copyright (c) 1999 - 2017, Intel Corp.
12  * All rights reserved.
13  *
14  * 2. License
15  *
16  * 2.1. This is your license from Intel Corp. under its intellectual property
17  * rights. You may have additional license terms from the party that provided
18  * you this software, covering your right to use that party's intellectual
19  * property rights.
20  *
21  * 2.2. Intel grants, free of charge, to any person ("Licensee") obtaining a
22  * copy of the source code appearing in this file ("Covered Code") an
23  * irrevocable, perpetual, worldwide license under Intel's copyrights in the
24  * base code distributed originally by Intel ("Original Intel Code") to copy,
25  * make derivatives, distribute, use and display any portion of the Covered
26  * Code in any form, with the right to sublicense such rights; and
27  *
28  * 2.3. Intel grants Licensee a non-exclusive and non-transferable patent
29  * license (with the right to sublicense), under only those claims of Intel
30  * patents that are infringed by the Original Intel Code, to make, use, sell,
31  * offer to sell, and import the Covered Code and derivative works thereof
32  * solely to the minimum extent necessary to exercise the above copyright
33  * license, and in no event shall the patent license extend to any additions
34  * to or modifications of the Original Intel Code. No other license or right
35  * is granted directly or by implication, estoppel or otherwise;
36  *
37  * The above copyright and patent license is granted only if the following
38  * conditions are met:
39  *
40  * 3. Conditions
41  *
42  * 3.1. Redistribution of Source with Rights to Further Distribute Source.
43  * Redistribution of source code of any substantial portion of the Covered
44  * Code or modification with rights to further distribute source must include
45  * the above Copyright Notice, the above License, this list of Conditions,
46  * and the following Disclaimer and Export Compliance provision. In addition,
47  * Licensee must cause all Covered Code to which Licensee contributes to
48  * contain a file documenting the changes Licensee made to create that Covered
49  * Code and the date of any change. Licensee must include in that file the
50  * documentation of any changes made by any predecessor Licensee. Licensee
51  * must include a prominent statement that the modification is derived,
52  * directly or indirectly, from Original Intel Code.
53  *
54  * 3.2. Redistribution of Source with no Rights to Further Distribute Source.
55  * Redistribution of source code of any substantial portion of the Covered
56  * Code or modification without rights to further distribute source must
57  * include the following Disclaimer and Export Compliance provision in the
58  * documentation and/or other materials provided with distribution. In
59  * addition, Licensee may not authorize further sublicense of source of any
60  * portion of the Covered Code, and must include terms to the effect that the
61  * license from Licensee to its licensee is limited to the intellectual
62  * property embodied in the software Licensee provides to its licensee, and
63  * not to intellectual property embodied in modifications its licensee may
64  * make.
65  *
66  * 3.3. Redistribution of Executable. Redistribution in executable form of any
67  * substantial portion of the Covered Code or modification must reproduce the
68  * above Copyright Notice, and the following Disclaimer and Export Compliance
69  * provision in the documentation and/or other materials provided with the
70  * distribution.
71  *
72  * 3.4. Intel retains all right, title, and interest in and to the Original
73  * Intel Code.
74  *
75  * 3.5. Neither the name Intel nor any other trademark owned or controlled by
76  * Intel shall be used in advertising or otherwise to promote the sale, use or
77  * other dealings in products derived from or relating to the Covered Code
78  * without prior written authorization from Intel.
79  *
80  * 4. Disclaimer and Export Compliance
81  *
82  * 4.1. INTEL MAKES NO WARRANTY OF ANY KIND REGARDING ANY SOFTWARE PROVIDED
83  * HERE. ANY SOFTWARE ORIGINATING FROM INTEL OR DERIVED FROM INTEL SOFTWARE
84  * IS PROVIDED "AS IS," AND INTEL WILL NOT PROVIDE ANY SUPPORT, ASSISTANCE,
85  * INSTALLATION, TRAINING OR OTHER SERVICES. INTEL WILL NOT PROVIDE ANY
86  * UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY DISCLAIMS ANY
87  * IMPLIED WARRANTIES OF MERCHANTABILITY, NONINFRINGEMENT AND FITNESS FOR A
88  * PARTICULAR PURPOSE.
89  *
90  * 4.2. IN NO EVENT SHALL INTEL HAVE ANY LIABILITY TO LICENSEE, ITS LICENSEES
91  * OR ANY OTHER THIRD PARTY, FOR ANY LOST PROFITS, LOST DATA, LOSS OF USE OR
92  * COSTS OF PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, OR FOR ANY INDIRECT,
93  * SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THIS AGREEMENT, UNDER ANY
94  * CAUSE OF ACTION OR THEORY OF LIABILITY, AND IRRESPECTIVE OF WHETHER INTEL
95  * HAS ADVANCE NOTICE OF THE POSSIBILITY OF SUCH DAMAGES. THESE LIMITATIONS
96  * SHALL APPLY NOTWITHSTANDING THE FAILURE OF THE ESSENTIAL PURPOSE OF ANY
97  * LIMITED REMEDY.
98  *
99  * 4.3. Licensee shall not export, either directly or indirectly, any of this
100  * software or system incorporating such software without first obtaining any
101  * required license or other approval from the U. S. Department of Commerce or
102  * any other agency or department of the United States Government. In the
103  * event Licensee exports any such software from the United States or
104  * re-exports any such software from a foreign destination, Licensee shall
105  * ensure that the distribution and export/re-export of the software is in
106  * compliance with all laws, regulations, orders, or other restrictions of the
107  * U.S. Export Administration Regulations. Licensee agrees that neither it nor
108  * any of its subsidiaries will export/re-export any technical data, process,
109  * software, or service, directly or indirectly, to any country for which the
110  * United States government or any agency thereof requires an export license,
111  * other governmental approval, or letter of assurance, without first obtaining
112  * such license, approval or letter.
113  *
114  *****************************************************************************
115  *
116  * Alternatively, you may choose to be licensed under the terms of the
117  * following license:
118  *
119  * Redistribution and use in source and binary forms, with or without
120  * modification, are permitted provided that the following conditions
121  * are met:
122  * 1. Redistributions of source code must retain the above copyright
123  *    notice, this list of conditions, and the following disclaimer,
124  *    without modification.
125  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
126  *    substantially similar to the "NO WARRANTY" disclaimer below
127  *    ("Disclaimer") and any redistribution must be conditioned upon
128  *    including a substantially similar Disclaimer requirement for further
129  *    binary redistribution.
130  * 3. Neither the names of the above-listed copyright holders nor the names
131  *    of any contributors may be used to endorse or promote products derived
132  *    from this software without specific prior written permission.
133  *
134  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
135  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
136  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
137  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
138  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
139  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
140  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
141  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
142  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
143  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
144  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
145  *
146  * Alternatively, you may choose to be licensed under the terms of the
147  * GNU General Public License ("GPL") version 2 as published by the Free
148  * Software Foundation.
149  *
150  *****************************************************************************/
151 
152 #include "aslcompiler.h"
153 
154 #define _COMPONENT          ACPI_COMPILER
155         ACPI_MODULE_NAME    ("aslerror")
156 
157 /* Local prototypes */
158 
159 static void
160 AeAddToErrorLog (
161     ASL_ERROR_MSG           *Enode);
162 
163 
164 /*******************************************************************************
165  *
166  * FUNCTION:    AslAbort
167  *
168  * PARAMETERS:  None
169  *
170  * RETURN:      None
171  *
172  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
173  *              I/O errors.
174  *
175  ******************************************************************************/
176 
177 void
178 AslAbort (
179     void)
180 {
181 
182     AePrintErrorLog (ASL_FILE_STDERR);
183     if (Gbl_DebugFlag)
184     {
185         /* Print error summary to stdout also */
186 
187         AePrintErrorLog (ASL_FILE_STDOUT);
188     }
189 
190     exit (1);
191 }
192 
193 
194 /*******************************************************************************
195  *
196  * FUNCTION:    AeClearErrorLog
197  *
198  * PARAMETERS:  None
199  *
200  * RETURN:      None
201  *
202  * DESCRIPTION: Empty the error list
203  *
204  ******************************************************************************/
205 
206 void
207 AeClearErrorLog (
208     void)
209 {
210     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
211     ASL_ERROR_MSG           *Next;
212 
213     /* Walk the error node list */
214 
215     while (Enode)
216     {
217         Next = Enode->Next;
218         ACPI_FREE (Enode);
219         Enode = Next;
220     }
221 
222     Gbl_ErrorLog = NULL;
223 }
224 
225 
226 /*******************************************************************************
227  *
228  * FUNCTION:    AeAddToErrorLog
229  *
230  * PARAMETERS:  Enode       - An error node to add to the log
231  *
232  * RETURN:      None
233  *
234  * DESCRIPTION: Add a new error node to the error log. The error log is
235  *              ordered by the "logical" line number (cumulative line number
236  *              including all include files.)
237  *
238  ******************************************************************************/
239 
240 static void
241 AeAddToErrorLog (
242     ASL_ERROR_MSG           *Enode)
243 {
244     ASL_ERROR_MSG           *Next;
245     ASL_ERROR_MSG           *Prev;
246 
247 
248     /* If Gbl_ErrorLog is null, this is the first error node */
249 
250     if (!Gbl_ErrorLog)
251     {
252         Gbl_ErrorLog = Enode;
253         return;
254     }
255 
256     /*
257      * Walk error list until we find a line number greater than ours.
258      * List is sorted according to line number.
259      */
260     Prev = NULL;
261     Next = Gbl_ErrorLog;
262 
263     while ((Next) &&
264            (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
265     {
266         Prev = Next;
267         Next = Next->Next;
268     }
269 
270     /* Found our place in the list */
271 
272     Enode->Next = Next;
273 
274     if (Prev)
275     {
276         Prev->Next = Enode;
277     }
278     else
279     {
280         Gbl_ErrorLog = Enode;
281     }
282 }
283 
284 
285 /*******************************************************************************
286  *
287  * FUNCTION:    AePrintException
288  *
289  * PARAMETERS:  FileId          - ID of output file
290  *              Enode           - Error node to print
291  *              Header          - Additional text before each message
292  *
293  * RETURN:      None
294  *
295  * DESCRIPTION: Print the contents of an error node.
296  *
297  * NOTE:        We don't use the FlxxxFile I/O functions here because on error
298  *              they abort the compiler and call this function!  Since we
299  *              are reporting errors here, we ignore most output errors and
300  *              just try to get out as much as we can.
301  *
302  ******************************************************************************/
303 
304 void
305 AePrintException (
306     UINT32                  FileId,
307     ASL_ERROR_MSG           *Enode,
308     char                    *Header)
309 {
310     UINT8                   SourceByte;
311     int                     Actual;
312     size_t                  RActual;
313     UINT32                  MsgLength;
314     const char              *MainMessage;
315     char                    *ExtraMessage;
316     UINT32                  SourceColumn;
317     UINT32                  ErrorColumn;
318     FILE                    *OutputFile;
319     FILE                    *SourceFile = NULL;
320     long                    FileSize;
321     BOOLEAN                 PrematureEOF = FALSE;
322     UINT32                  Total = 0;
323 
324 
325     if (Gbl_NoErrors)
326     {
327         return;
328     }
329 
330     /*
331      * Only listing files have a header, and remarks/optimizations
332      * are always output
333      */
334     if (!Header)
335     {
336         /* Ignore remarks if requested */
337 
338         switch (Enode->Level)
339         {
340         case ASL_WARNING:
341         case ASL_WARNING2:
342         case ASL_WARNING3:
343 
344             if (!Gbl_DisplayWarnings)
345             {
346                 return;
347             }
348             break;
349 
350         case ASL_REMARK:
351 
352             if (!Gbl_DisplayRemarks)
353             {
354                 return;
355             }
356             break;
357 
358         case ASL_OPTIMIZATION:
359 
360             if (!Gbl_DisplayOptimizations)
361             {
362                 return;
363             }
364             break;
365 
366         default:
367 
368             break;
369         }
370     }
371 
372     /* Get the various required file handles */
373 
374     OutputFile = Gbl_Files[FileId].Handle;
375 
376     if (!Enode->SourceLine)
377     {
378         /*
379          * Use the merged header/source file if present, otherwise
380          * use input file
381          */
382         SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
383         if (!SourceFile)
384         {
385             SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
386         }
387 
388         if (SourceFile)
389         {
390             /* Determine if the error occurred at source file EOF */
391 
392             fseek (SourceFile, 0, SEEK_END);
393             FileSize = ftell (SourceFile);
394 
395             if ((long) Enode->LogicalByteOffset >= FileSize)
396             {
397                 PrematureEOF = TRUE;
398             }
399         }
400     }
401 
402     if (Header)
403     {
404         fprintf (OutputFile, "%s", Header);
405     }
406 
407     /* Print filename and line number if present and valid */
408 
409     if (Enode->Filename)
410     {
411         if (Gbl_VerboseErrors)
412         {
413             fprintf (OutputFile, "%-8s", Enode->Filename);
414 
415             if (Enode->LineNumber)
416             {
417                 if (Enode->SourceLine)
418                 {
419                     fprintf (OutputFile, " %6u: %s",
420                         Enode->LineNumber, Enode->SourceLine);
421                 }
422                 else
423                 {
424                     fprintf (OutputFile, " %6u: ", Enode->LineNumber);
425 
426                     /*
427                      * If not at EOF, get the corresponding source code line
428                      * and display it. Don't attempt this if we have a
429                      * premature EOF condition.
430                      */
431                     if (!PrematureEOF)
432                     {
433                         /*
434                          * Seek to the offset in the combined source file,
435                          * read the source line, and write it to the output.
436                          */
437                         Actual = fseek (SourceFile,
438                             (long) Enode->LogicalByteOffset, (int) SEEK_SET);
439                         if (Actual)
440                         {
441                             fprintf (OutputFile,
442                                 "[*** iASL: Seek error on source code temp file %s ***]",
443                                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
444                         }
445                         else
446                         {
447                             RActual = fread (&SourceByte, 1, 1, SourceFile);
448                             if (RActual != 1)
449                             {
450                                 fprintf (OutputFile,
451                                     "[*** iASL: Read error on source code temp file %s ***]",
452                                     Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
453                             }
454                             else
455                             {
456                                 /* Read/write the source line, up to the maximum line length */
457 
458                                 while (RActual && SourceByte && (SourceByte != '\n'))
459                                 {
460                                     if (Total < 256)
461                                     {
462                                         /* After the max line length, we will just read the line, no write */
463 
464                                         if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
465                                         {
466                                             printf ("[*** iASL: Write error on output file ***]\n");
467                                             return;
468                                         }
469                                     }
470                                     else if (Total == 256)
471                                     {
472                                         fprintf (OutputFile,
473                                             "\n[*** iASL: Very long input line, message below refers to column %u ***]",
474                                             Enode->Column);
475                                     }
476 
477                                     RActual = fread (&SourceByte, 1, 1, SourceFile);
478                                     if (RActual != 1)
479                                     {
480                                         fprintf (OutputFile,
481                                             "[*** iASL: Read error on source code temp file %s ***]",
482                                             Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
483                                         return;
484                                     }
485                                     Total++;
486                                 }
487                             }
488                         }
489                     }
490 
491                     fprintf (OutputFile, "\n");
492                 }
493             }
494         }
495         else
496         {
497             /*
498              * Less verbose version of the error message, enabled via the
499              * -vi switch. The format is compatible with MS Visual Studio.
500              */
501             fprintf (OutputFile, "%s", Enode->Filename);
502 
503             if (Enode->LineNumber)
504             {
505                 fprintf (OutputFile, "(%u) : ",
506                     Enode->LineNumber);
507             }
508         }
509     }
510 
511     /* If a NULL message ID, just print the raw message */
512 
513     if (Enode->MessageId == 0)
514     {
515         fprintf (OutputFile, "%s\n", Enode->Message);
516         return;
517     }
518 
519     /* Decode the message ID */
520 
521     fprintf (OutputFile, "%s %4.4d -",
522         AeDecodeExceptionLevel (Enode->Level),
523         AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
524 
525     MainMessage = AeDecodeMessageId (Enode->MessageId);
526     ExtraMessage = Enode->Message;
527 
528     /* If a NULL line number, just print the decoded message */
529 
530     if (!Enode->LineNumber)
531     {
532         fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
533         return;
534     }
535 
536     MsgLength = strlen (MainMessage);
537     if (MsgLength == 0)
538     {
539         /* Use the secondary/extra message as main message */
540 
541         MainMessage = Enode->Message;
542         if (!MainMessage)
543         {
544             MainMessage = "";
545         }
546 
547         MsgLength = strlen (MainMessage);
548         ExtraMessage = NULL;
549     }
550 
551     if (Gbl_VerboseErrors && !PrematureEOF)
552     {
553         if (Total >= 256)
554         {
555             fprintf (OutputFile, "    %s",
556                 MainMessage);
557         }
558         else
559         {
560             SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
561             ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
562 
563             if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
564             {
565                 fprintf (OutputFile, "%*s%s",
566                     (int) ((SourceColumn - 1) - ErrorColumn),
567                     MainMessage, " ^ ");
568             }
569             else
570             {
571                 fprintf (OutputFile, "%*s %s",
572                     (int) ((SourceColumn - ErrorColumn) + 1), "^",
573                     MainMessage);
574             }
575         }
576     }
577     else
578     {
579         fprintf (OutputFile, " %s", MainMessage);
580     }
581 
582     /* Print the extra info message if present */
583 
584     if (ExtraMessage)
585     {
586         fprintf (OutputFile, " (%s)", ExtraMessage);
587     }
588 
589     if (PrematureEOF)
590     {
591         fprintf (OutputFile, " and premature End-Of-File");
592     }
593 
594     fprintf (OutputFile, "\n");
595     if (Gbl_VerboseErrors)
596     {
597         fprintf (OutputFile, "\n");
598     }
599 }
600 
601 
602 /*******************************************************************************
603  *
604  * FUNCTION:    AePrintErrorLog
605  *
606  * PARAMETERS:  FileId           - Where to output the error log
607  *
608  * RETURN:      None
609  *
610  * DESCRIPTION: Print the entire contents of the error log
611  *
612  ******************************************************************************/
613 
614 void
615 AePrintErrorLog (
616     UINT32                  FileId)
617 {
618     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
619 
620 
621     /* Walk the error node list */
622 
623     while (Enode)
624     {
625         AePrintException (FileId, Enode, NULL);
626         Enode = Enode->Next;
627     }
628 }
629 
630 
631 /*******************************************************************************
632  *
633  * FUNCTION:    AslCommonError2
634  *
635  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
636  *              MessageId           - Index into global message buffer
637  *              LineNumber          - Actual file line number
638  *              Column              - Column in current line
639  *              SourceLine          - Actual source code line
640  *              Filename            - source filename
641  *              ExtraMessage        - additional error message
642  *
643  * RETURN:      None
644  *
645  * DESCRIPTION: Create a new error node and add it to the error log
646  *
647  ******************************************************************************/
648 
649 void
650 AslCommonError2 (
651     UINT8                   Level,
652     UINT16                  MessageId,
653     UINT32                  LineNumber,
654     UINT32                  Column,
655     char                    *SourceLine,
656     char                    *Filename,
657     char                    *ExtraMessage)
658 {
659     char                    *MessageBuffer = NULL;
660     char                    *LineBuffer;
661     ASL_ERROR_MSG           *Enode;
662 
663 
664     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
665 
666     if (ExtraMessage)
667     {
668         /* Allocate a buffer for the message and a new error node */
669 
670         MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
671 
672         /* Keep a copy of the extra message */
673 
674         strcpy (MessageBuffer, ExtraMessage);
675     }
676 
677     LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
678     strcpy (LineBuffer, SourceLine);
679 
680     /* Initialize the error node */
681 
682     if (Filename)
683     {
684         Enode->Filename = Filename;
685         Enode->FilenameLength = strlen (Filename);
686         if (Enode->FilenameLength < 6)
687         {
688             Enode->FilenameLength = 6;
689         }
690     }
691 
692     Enode->MessageId            = MessageId;
693     Enode->Level                = Level;
694     Enode->LineNumber           = LineNumber;
695     Enode->LogicalLineNumber    = LineNumber;
696     Enode->LogicalByteOffset    = 0;
697     Enode->Column               = Column;
698     Enode->Message              = MessageBuffer;
699     Enode->SourceLine           = LineBuffer;
700 
701     /* Add the new node to the error node list */
702 
703     AeAddToErrorLog (Enode);
704 
705     if (Gbl_DebugFlag)
706     {
707         /* stderr is a file, send error to it immediately */
708 
709         AePrintException (ASL_FILE_STDERR, Enode, NULL);
710     }
711 
712     Gbl_ExceptionCount[Level]++;
713 }
714 
715 
716 /*******************************************************************************
717  *
718  * FUNCTION:    AslCommonError
719  *
720  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
721  *              MessageId           - Index into global message buffer
722  *              CurrentLineNumber   - Actual file line number
723  *              LogicalLineNumber   - Cumulative line number
724  *              LogicalByteOffset   - Byte offset in source file
725  *              Column              - Column in current line
726  *              Filename            - source filename
727  *              ExtraMessage        - additional error message
728  *
729  * RETURN:      None
730  *
731  * DESCRIPTION: Create a new error node and add it to the error log
732  *
733  ******************************************************************************/
734 
735 void
736 AslCommonError (
737     UINT8                   Level,
738     UINT16                  MessageId,
739     UINT32                  CurrentLineNumber,
740     UINT32                  LogicalLineNumber,
741     UINT32                  LogicalByteOffset,
742     UINT32                  Column,
743     char                    *Filename,
744     char                    *ExtraMessage)
745 {
746     char                    *MessageBuffer = NULL;
747     ASL_ERROR_MSG           *Enode;
748 
749 
750     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
751 
752     if (ExtraMessage)
753     {
754         /* Allocate a buffer for the message and a new error node */
755 
756         MessageBuffer = UtStringCacheCalloc (strlen (ExtraMessage) + 1);
757 
758         /* Keep a copy of the extra message */
759 
760         strcpy (MessageBuffer, ExtraMessage);
761     }
762 
763     /* Initialize the error node */
764 
765     if (Filename)
766     {
767         Enode->Filename = Filename;
768         Enode->FilenameLength = strlen (Filename);
769         if (Enode->FilenameLength < 6)
770         {
771             Enode->FilenameLength = 6;
772         }
773     }
774 
775     Enode->MessageId            = MessageId;
776     Enode->Level                = Level;
777     Enode->LineNumber           = CurrentLineNumber;
778     Enode->LogicalLineNumber    = LogicalLineNumber;
779     Enode->LogicalByteOffset    = LogicalByteOffset;
780     Enode->Column               = Column;
781     Enode->Message              = MessageBuffer;
782     Enode->SourceLine           = NULL;
783 
784     /* Add the new node to the error node list */
785 
786     AeAddToErrorLog (Enode);
787 
788     if (Gbl_DebugFlag)
789     {
790         /* stderr is a file, send error to it immediately */
791 
792         AePrintException (ASL_FILE_STDERR, Enode, NULL);
793     }
794 
795     Gbl_ExceptionCount[Level]++;
796     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
797     {
798         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
799 
800         Gbl_SourceLine = 0;
801         Gbl_NextError = Gbl_ErrorLog;
802         CmCleanupAndExit ();
803         exit(1);
804     }
805 
806     return;
807 }
808 
809 
810 /*******************************************************************************
811  *
812  * FUNCTION:    AslDisableException
813  *
814  * PARAMETERS:  MessageIdString     - ID to be disabled
815  *
816  * RETURN:      Status
817  *
818  * DESCRIPTION: Enter a message ID into the global disabled messages table
819  *
820  ******************************************************************************/
821 
822 ACPI_STATUS
823 AslDisableException (
824     char                    *MessageIdString)
825 {
826     UINT32                  MessageId;
827 
828 
829     /* Convert argument to an integer and validate it */
830 
831     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
832 
833     if ((MessageId < 2000) || (MessageId > 5999))
834     {
835         printf ("\"%s\" is not a valid warning/remark ID\n",
836             MessageIdString);
837         return (AE_BAD_PARAMETER);
838     }
839 
840     /* Insert value into the global disabled message array */
841 
842     if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
843     {
844         printf ("Too many messages have been disabled (max %u)\n",
845             ASL_MAX_DISABLED_MESSAGES);
846         return (AE_LIMIT);
847     }
848 
849     Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
850     Gbl_DisabledMessagesIndex++;
851     return (AE_OK);
852 }
853 
854 
855 /*******************************************************************************
856  *
857  * FUNCTION:    AslIsExceptionDisabled
858  *
859  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
860  *              MessageId           - Index into global message buffer
861  *
862  * RETURN:      TRUE if exception/message should be ignored
863  *
864  * DESCRIPTION: Check if the user has specified options such that this
865  *              exception should be ignored
866  *
867  ******************************************************************************/
868 
869 BOOLEAN
870 AslIsExceptionDisabled (
871     UINT8                   Level,
872     UINT16                  MessageId)
873 {
874     UINT32                  EncodedMessageId;
875     UINT32                  i;
876 
877 
878     switch (Level)
879     {
880     case ASL_WARNING2:
881     case ASL_WARNING3:
882 
883         /* Check for global disable via -w1/-w2/-w3 options */
884 
885         if (Level > Gbl_WarningLevel)
886         {
887             return (TRUE);
888         }
889         /* Fall through */
890 
891     case ASL_WARNING:
892     case ASL_REMARK:
893         /*
894          * Ignore this warning/remark if it has been disabled by
895          * the user (-vw option)
896          */
897         EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
898         for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
899         {
900             /* Simple implementation via fixed array */
901 
902             if (EncodedMessageId == Gbl_DisabledMessages[i])
903             {
904                 return (TRUE);
905             }
906         }
907         break;
908 
909     default:
910         break;
911     }
912 
913     return (FALSE);
914 }
915 
916 
917 /*******************************************************************************
918  *
919  * FUNCTION:    AslError
920  *
921  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
922  *              MessageId           - Index into global message buffer
923  *              Op                  - Parse node where error happened
924  *              ExtraMessage        - additional error message
925  *
926  * RETURN:      None
927  *
928  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
929  *              except the parser.)
930  *
931  ******************************************************************************/
932 
933 void
934 AslError (
935     UINT8                   Level,
936     UINT16                  MessageId,
937     ACPI_PARSE_OBJECT       *Op,
938     char                    *ExtraMessage)
939 {
940 
941     /* Check if user wants to ignore this exception */
942 
943     if (Gbl_AllExceptionsDisabled ||
944         AslIsExceptionDisabled (Level, MessageId))
945     {
946         return;
947     }
948 
949     if (Op)
950     {
951         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
952             Op->Asl.LogicalLineNumber,
953             Op->Asl.LogicalByteOffset,
954             Op->Asl.Column,
955             Op->Asl.Filename, ExtraMessage);
956     }
957     else
958     {
959         AslCommonError (Level, MessageId, 0,
960             0, 0, 0, NULL, ExtraMessage);
961     }
962 }
963 
964 
965 /*******************************************************************************
966  *
967  * FUNCTION:    AslCoreSubsystemError
968  *
969  * PARAMETERS:  Op                  - Parse node where error happened
970  *              Status              - The ACPICA Exception
971  *              ExtraMessage        - additional error message
972  *              Abort               - TRUE -> Abort compilation
973  *
974  * RETURN:      None
975  *
976  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
977  *              core subsystem.
978  *
979  ******************************************************************************/
980 
981 void
982 AslCoreSubsystemError (
983     ACPI_PARSE_OBJECT       *Op,
984     ACPI_STATUS             Status,
985     char                    *ExtraMessage,
986     BOOLEAN                 Abort)
987 {
988 
989     sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
990 
991     if (Op)
992     {
993         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
994             Op->Asl.LineNumber,
995             Op->Asl.LogicalLineNumber,
996             Op->Asl.LogicalByteOffset,
997             Op->Asl.Column,
998             Op->Asl.Filename, MsgBuffer);
999     }
1000     else
1001     {
1002         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
1003             0, 0, 0, 0, NULL, MsgBuffer);
1004     }
1005 
1006     if (Abort)
1007     {
1008         AslAbort ();
1009     }
1010 }
1011 
1012 
1013 /*******************************************************************************
1014  *
1015  * FUNCTION:    AslCompilererror
1016  *
1017  * PARAMETERS:  CompilerMessage         - Error message from the parser
1018  *
1019  * RETURN:      Status (0 for now)
1020  *
1021  * DESCRIPTION: Report an error situation discovered in a production
1022  *              NOTE: don't change the name of this function, it is called
1023  *              from the auto-generated parser.
1024  *
1025  ******************************************************************************/
1026 
1027 int
1028 AslCompilererror (
1029     const char              *CompilerMessage)
1030 {
1031 
1032     Gbl_SyntaxError++;
1033 
1034     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
1035         Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
1036         Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
1037         ACPI_CAST_PTR (char, CompilerMessage));
1038 
1039     return (0);
1040 }
1041