1 /******************************************************************************
2  *
3  * Module Name: aslerror - Error handling and statistics
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2013, 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 #define ASL_EXCEPTIONS
45 #include "aslcompiler.h"
46 
47 #define _COMPONENT          ACPI_COMPILER
48         ACPI_MODULE_NAME    ("aslerror")
49 
50 /* Local prototypes */
51 
52 static void
53 AeAddToErrorLog (
54     ASL_ERROR_MSG           *Enode);
55 
56 
57 /*******************************************************************************
58  *
59  * FUNCTION:    AeClearErrorLog
60  *
61  * PARAMETERS:  None
62  *
63  * RETURN:      None
64  *
65  * DESCRIPTION: Empty the error list
66  *
67  ******************************************************************************/
68 
69 void
70 AeClearErrorLog (
71     void)
72 {
73     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
74     ASL_ERROR_MSG           *Next;
75 
76     /* Walk the error node list */
77 
78     while (Enode)
79     {
80         Next = Enode->Next;
81         ACPI_FREE (Enode);
82         Enode = Next;
83     }
84 
85     Gbl_ErrorLog = NULL;
86 }
87 
88 
89 /*******************************************************************************
90  *
91  * FUNCTION:    AeAddToErrorLog
92  *
93  * PARAMETERS:  Enode       - An error node to add to the log
94  *
95  * RETURN:      None
96  *
97  * DESCRIPTION: Add a new error node to the error log. The error log is
98  *              ordered by the "logical" line number (cumulative line number
99  *              including all include files.)
100  *
101  ******************************************************************************/
102 
103 static void
104 AeAddToErrorLog (
105     ASL_ERROR_MSG           *Enode)
106 {
107     ASL_ERROR_MSG           *Next;
108     ASL_ERROR_MSG           *Prev;
109 
110 
111     /* If Gbl_ErrorLog is null, this is the first error node */
112 
113     if (!Gbl_ErrorLog)
114     {
115         Gbl_ErrorLog = Enode;
116         return;
117     }
118 
119     /*
120      * Walk error list until we find a line number greater than ours.
121      * List is sorted according to line number.
122      */
123     Prev = NULL;
124     Next = Gbl_ErrorLog;
125 
126     while ((Next) &&
127            (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
128     {
129         Prev = Next;
130         Next = Next->Next;
131     }
132 
133     /* Found our place in the list */
134 
135     Enode->Next = Next;
136 
137     if (Prev)
138     {
139         Prev->Next = Enode;
140     }
141     else
142     {
143         Gbl_ErrorLog = Enode;
144     }
145 }
146 
147 
148 /*******************************************************************************
149  *
150  * FUNCTION:    AePrintException
151  *
152  * PARAMETERS:  FileId          - ID of output file
153  *              Enode           - Error node to print
154  *              Header          - Additional text before each message
155  *
156  * RETURN:      None
157  *
158  * DESCRIPTION: Print the contents of an error node.
159  *
160  * NOTE:        We don't use the FlxxxFile I/O functions here because on error
161  *              they abort the compiler and call this function!  Since we
162  *              are reporting errors here, we ignore most output errors and
163  *              just try to get out as much as we can.
164  *
165  ******************************************************************************/
166 
167 void
168 AePrintException (
169     UINT32                  FileId,
170     ASL_ERROR_MSG           *Enode,
171     char                    *Header)
172 {
173     UINT8                   SourceByte;
174     int                     Actual;
175     size_t                  RActual;
176     UINT32                  MsgLength;
177     char                    *MainMessage;
178     char                    *ExtraMessage;
179     UINT32                  SourceColumn;
180     UINT32                  ErrorColumn;
181     FILE                    *OutputFile;
182     FILE                    *SourceFile = NULL;
183     long                    FileSize;
184     BOOLEAN                 PrematureEOF = FALSE;
185     UINT32                  Total = 0;
186 
187 
188     if (Gbl_NoErrors)
189     {
190         return;
191     }
192 
193     /*
194      * Only listing files have a header, and remarks/optimizations
195      * are always output
196      */
197     if (!Header)
198     {
199         /* Ignore remarks if requested */
200 
201         switch (Enode->Level)
202         {
203         case ASL_WARNING:
204         case ASL_WARNING2:
205         case ASL_WARNING3:
206 
207             if (!Gbl_DisplayWarnings)
208             {
209                 return;
210             }
211             break;
212 
213         case ASL_REMARK:
214 
215             if (!Gbl_DisplayRemarks)
216             {
217                 return;
218             }
219             break;
220 
221         case ASL_OPTIMIZATION:
222 
223             if (!Gbl_DisplayOptimizations)
224             {
225                 return;
226             }
227             break;
228 
229         default:
230 
231             break;
232         }
233     }
234 
235     /* Get the various required file handles */
236 
237     OutputFile = Gbl_Files[FileId].Handle;
238 
239     if (!Enode->SourceLine)
240     {
241         /* Use the merged header/source file if present, otherwise use input file */
242 
243         SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
244         if (!SourceFile)
245         {
246             SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
247         }
248 
249         if (SourceFile)
250         {
251             /* Determine if the error occurred at source file EOF */
252 
253             fseek (SourceFile, 0, SEEK_END);
254             FileSize = ftell (SourceFile);
255 
256             if ((long) Enode->LogicalByteOffset >= FileSize)
257             {
258                 PrematureEOF = TRUE;
259             }
260         }
261     }
262 
263     if (Header)
264     {
265         fprintf (OutputFile, "%s", Header);
266     }
267 
268     /* Print filename and line number if present and valid */
269 
270     if (Enode->Filename)
271     {
272         if (Gbl_VerboseErrors)
273         {
274             fprintf (OutputFile, "%-8s", Enode->Filename);
275 
276             if (Enode->LineNumber)
277             {
278                 if (Enode->SourceLine)
279                 {
280                     fprintf (OutputFile, " %6u: %s",
281                         Enode->LineNumber, Enode->SourceLine);
282                 }
283                 else
284                 {
285                     fprintf (OutputFile, " %6u: ", Enode->LineNumber);
286 
287                     /*
288                      * If not at EOF, get the corresponding source code line and
289                      * display it. Don't attempt this if we have a premature EOF
290                      * condition.
291                      */
292                     if (!PrematureEOF)
293                     {
294                         /*
295                          * Seek to the offset in the combined source file, read
296                          * the source line, and write it to the output.
297                          */
298                         Actual = fseek (SourceFile, (long) Enode->LogicalByteOffset,
299                                     (int) SEEK_SET);
300                         if (Actual)
301                         {
302                             fprintf (OutputFile,
303                                 "[*** iASL: Seek error on source code temp file %s ***]",
304                                 Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
305                         }
306                         else
307                         {
308                             RActual = fread (&SourceByte, 1, 1, SourceFile);
309                             if (RActual != 1)
310                             {
311                                 fprintf (OutputFile,
312                                     "[*** iASL: Read error on source code temp file %s ***]",
313                                     Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
314                             }
315                             else
316                             {
317                                 /* Read/write the source line, up to the maximum line length */
318 
319                                 while (RActual && SourceByte && (SourceByte != '\n'))
320                                 {
321                                     if (Total < 256)
322                                     {
323                                         /* After the max line length, we will just read the line, no write */
324 
325                                         if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
326                                         {
327                                             printf ("[*** iASL: Write error on output file ***]\n");
328                                             return;
329                                         }
330                                     }
331                                     else if (Total == 256)
332                                     {
333                                         fprintf (OutputFile,
334                                             "\n[*** iASL: Very long input line, message below refers to column %u ***]",
335                                             Enode->Column);
336                                     }
337 
338                                     RActual = fread (&SourceByte, 1, 1, SourceFile);
339                                     if (RActual != 1)
340                                     {
341                                         fprintf (OutputFile,
342                                             "[*** iASL: Read error on source code temp file %s ***]",
343                                             Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
344                                         return;
345                                     }
346                                     Total++;
347                                 }
348                             }
349                         }
350                     }
351 
352                     fprintf (OutputFile, "\n");
353                 }
354             }
355         }
356         else
357         {
358             /*
359              * Less verbose version of the error message, enabled via the
360              * -vi switch. The format is compatible with MS Visual Studio.
361              */
362             fprintf (OutputFile, "%s", Enode->Filename);
363 
364             if (Enode->LineNumber)
365             {
366                 fprintf (OutputFile, "(%u) : ",
367                     Enode->LineNumber);
368             }
369         }
370     }
371 
372     /* NULL message ID, just print the raw message */
373 
374     if (Enode->MessageId == 0)
375     {
376         fprintf (OutputFile, "%s\n", Enode->Message);
377     }
378     else
379     {
380         /* Decode the message ID */
381 
382         if (Gbl_VerboseErrors)
383         {
384             fprintf (OutputFile, "%s %4.4d -",
385                         AslErrorLevel[Enode->Level],
386                         Enode->MessageId + ((Enode->Level+1) * 1000));
387         }
388         else /* IDE case */
389         {
390             fprintf (OutputFile, "%s %4.4d:",
391                         AslErrorLevelIde[Enode->Level],
392                         Enode->MessageId + ((Enode->Level+1) * 1000));
393         }
394 
395         MainMessage = AslMessages[Enode->MessageId];
396         ExtraMessage = Enode->Message;
397 
398         if (Enode->LineNumber)
399         {
400             /* Main message: try to use string from AslMessages first */
401 
402             if (!MainMessage)
403             {
404                 MainMessage = "";
405             }
406 
407             MsgLength = strlen (MainMessage);
408             if (MsgLength == 0)
409             {
410                 /* Use the secondary/extra message as main message */
411 
412                 MainMessage = Enode->Message;
413                 if (!MainMessage)
414                 {
415                     MainMessage = "";
416                 }
417 
418                 MsgLength = strlen (MainMessage);
419                 ExtraMessage = NULL;
420             }
421 
422             if (Gbl_VerboseErrors && !PrematureEOF)
423             {
424                 if (Total >= 256)
425                 {
426                     fprintf (OutputFile, "    %s",
427                         MainMessage);
428                 }
429                 else
430                 {
431                     SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
432                     ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
433 
434                     if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
435                     {
436                         fprintf (OutputFile, "%*s%s",
437                             (int) ((SourceColumn - 1) - ErrorColumn),
438                             MainMessage, " ^ ");
439                     }
440                     else
441                     {
442                         fprintf (OutputFile, "%*s %s",
443                             (int) ((SourceColumn - ErrorColumn) + 1), "^",
444                             MainMessage);
445                     }
446                 }
447             }
448             else
449             {
450                 fprintf (OutputFile, " %s", MainMessage);
451             }
452 
453             /* Print the extra info message if present */
454 
455             if (ExtraMessage)
456             {
457                 fprintf (OutputFile, " (%s)", ExtraMessage);
458             }
459 
460             if (PrematureEOF)
461             {
462                 fprintf (OutputFile, " and premature End-Of-File");
463             }
464 
465             fprintf (OutputFile, "\n");
466             if (Gbl_VerboseErrors)
467             {
468                 fprintf (OutputFile, "\n");
469             }
470         }
471         else
472         {
473             fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
474         }
475     }
476 }
477 
478 
479 /*******************************************************************************
480  *
481  * FUNCTION:    AePrintErrorLog
482  *
483  * PARAMETERS:  FileId           - Where to output the error log
484  *
485  * RETURN:      None
486  *
487  * DESCRIPTION: Print the entire contents of the error log
488  *
489  ******************************************************************************/
490 
491 void
492 AePrintErrorLog (
493     UINT32                  FileId)
494 {
495     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
496 
497 
498     /* Walk the error node list */
499 
500     while (Enode)
501     {
502         AePrintException (FileId, Enode, NULL);
503         Enode = Enode->Next;
504     }
505 }
506 
507 
508 /*******************************************************************************
509  *
510  * FUNCTION:    AslCommonError2
511  *
512  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
513  *              MessageId           - Index into global message buffer
514  *              LineNumber          - Actual file line number
515  *              Column              - Column in current line
516  *              SourceLine          - Actual source code line
517  *              Filename            - source filename
518  *              ExtraMessage        - additional error message
519  *
520  * RETURN:      None
521  *
522  * DESCRIPTION: Create a new error node and add it to the error log
523  *
524  ******************************************************************************/
525 
526 void
527 AslCommonError2 (
528     UINT8                   Level,
529     UINT8                   MessageId,
530     UINT32                  LineNumber,
531     UINT32                  Column,
532     char                    *SourceLine,
533     char                    *Filename,
534     char                    *ExtraMessage)
535 {
536     char                    *MessageBuffer = NULL;
537     char                    *LineBuffer;
538     ASL_ERROR_MSG           *Enode;
539 
540 
541     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
542 
543     if (ExtraMessage)
544     {
545         /* Allocate a buffer for the message and a new error node */
546 
547         MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
548 
549         /* Keep a copy of the extra message */
550 
551         ACPI_STRCPY (MessageBuffer, ExtraMessage);
552     }
553 
554     LineBuffer = UtLocalCalloc (strlen (SourceLine) + 1);
555     ACPI_STRCPY (LineBuffer, SourceLine);
556 
557     /* Initialize the error node */
558 
559     if (Filename)
560     {
561         Enode->Filename       = Filename;
562         Enode->FilenameLength = strlen (Filename);
563         if (Enode->FilenameLength < 6)
564         {
565             Enode->FilenameLength = 6;
566         }
567     }
568 
569     Enode->MessageId            = MessageId;
570     Enode->Level                = Level;
571     Enode->LineNumber           = LineNumber;
572     Enode->LogicalLineNumber    = LineNumber;
573     Enode->LogicalByteOffset    = 0;
574     Enode->Column               = Column;
575     Enode->Message              = MessageBuffer;
576     Enode->SourceLine           = LineBuffer;
577 
578     /* Add the new node to the error node list */
579 
580     AeAddToErrorLog (Enode);
581 
582     if (Gbl_DebugFlag)
583     {
584         /* stderr is a file, send error to it immediately */
585 
586         AePrintException (ASL_FILE_STDERR, Enode, NULL);
587     }
588 
589     Gbl_ExceptionCount[Level]++;
590 }
591 
592 
593 /*******************************************************************************
594  *
595  * FUNCTION:    AslCommonError
596  *
597  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
598  *              MessageId           - Index into global message buffer
599  *              CurrentLineNumber   - Actual file line number
600  *              LogicalLineNumber   - Cumulative line number
601  *              LogicalByteOffset   - Byte offset in source file
602  *              Column              - Column in current line
603  *              Filename            - source filename
604  *              ExtraMessage        - additional error message
605  *
606  * RETURN:      None
607  *
608  * DESCRIPTION: Create a new error node and add it to the error log
609  *
610  ******************************************************************************/
611 
612 void
613 AslCommonError (
614     UINT8                   Level,
615     UINT8                   MessageId,
616     UINT32                  CurrentLineNumber,
617     UINT32                  LogicalLineNumber,
618     UINT32                  LogicalByteOffset,
619     UINT32                  Column,
620     char                    *Filename,
621     char                    *ExtraMessage)
622 {
623     char                    *MessageBuffer = NULL;
624     ASL_ERROR_MSG           *Enode;
625 
626 
627     Enode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
628 
629     if (ExtraMessage)
630     {
631         /* Allocate a buffer for the message and a new error node */
632 
633         MessageBuffer = UtLocalCalloc (strlen (ExtraMessage) + 1);
634 
635         /* Keep a copy of the extra message */
636 
637         ACPI_STRCPY (MessageBuffer, ExtraMessage);
638     }
639 
640     /* Initialize the error node */
641 
642     if (Filename)
643     {
644         Enode->Filename       = Filename;
645         Enode->FilenameLength = strlen (Filename);
646         if (Enode->FilenameLength < 6)
647         {
648             Enode->FilenameLength = 6;
649         }
650     }
651 
652     Enode->MessageId            = MessageId;
653     Enode->Level                = Level;
654     Enode->LineNumber           = CurrentLineNumber;
655     Enode->LogicalLineNumber    = LogicalLineNumber;
656     Enode->LogicalByteOffset    = LogicalByteOffset;
657     Enode->Column               = Column;
658     Enode->Message              = MessageBuffer;
659     Enode->SourceLine           = NULL;
660 
661     /* Add the new node to the error node list */
662 
663     AeAddToErrorLog (Enode);
664 
665     if (Gbl_DebugFlag)
666     {
667         /* stderr is a file, send error to it immediately */
668 
669         AePrintException (ASL_FILE_STDERR, Enode, NULL);
670     }
671 
672     Gbl_ExceptionCount[Level]++;
673     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
674     {
675         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
676 
677         Gbl_SourceLine = 0;
678         Gbl_NextError = Gbl_ErrorLog;
679         CmCleanupAndExit ();
680         exit(1);
681     }
682 
683     return;
684 }
685 
686 
687 /*******************************************************************************
688  *
689  * FUNCTION:    AslDisableException
690  *
691  * PARAMETERS:  MessageIdString     - ID to be disabled
692  *
693  * RETURN:      Status
694  *
695  * DESCRIPTION: Enter a message ID into the global disabled messages table
696  *
697  ******************************************************************************/
698 
699 ACPI_STATUS
700 AslDisableException (
701     char                    *MessageIdString)
702 {
703     UINT32                  MessageId;
704 
705 
706     /* Convert argument to an integer and validate it */
707 
708     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
709 
710     if ((MessageId < 2000) || (MessageId > 5999))
711     {
712         printf ("\"%s\" is not a valid warning/remark ID\n",
713             MessageIdString);
714         return (AE_BAD_PARAMETER);
715     }
716 
717     /* Insert value into the global disabled message array */
718 
719     if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
720     {
721         printf ("Too many messages have been disabled (max %u)\n",
722             ASL_MAX_DISABLED_MESSAGES);
723         return (AE_LIMIT);
724     }
725 
726     Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
727     Gbl_DisabledMessagesIndex++;
728     return (AE_OK);
729 }
730 
731 
732 /*******************************************************************************
733  *
734  * FUNCTION:    AslIsExceptionDisabled
735  *
736  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
737  *              MessageId           - Index into global message buffer
738  *
739  * RETURN:      TRUE if exception/message should be ignored
740  *
741  * DESCRIPTION: Check if the user has specified options such that this
742  *              exception should be ignored
743  *
744  ******************************************************************************/
745 
746 BOOLEAN
747 AslIsExceptionDisabled (
748     UINT8                   Level,
749     UINT8                   MessageId)
750 {
751     UINT32                  EncodedMessageId;
752     UINT32                  i;
753 
754 
755     switch (Level)
756     {
757     case ASL_WARNING2:
758     case ASL_WARNING3:
759 
760         /* Check for global disable via -w1/-w2/-w3 options */
761 
762         if (Level > Gbl_WarningLevel)
763         {
764             return (TRUE);
765         }
766         /* Fall through */
767 
768     case ASL_WARNING:
769     case ASL_REMARK:
770         /*
771          * Ignore this warning/remark if it has been disabled by
772          * the user (-vw option)
773          */
774         EncodedMessageId = MessageId + ((Level + 1) * 1000);
775         for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
776         {
777             /* Simple implementation via fixed array */
778 
779             if (EncodedMessageId == Gbl_DisabledMessages[i])
780             {
781                 return (TRUE);
782             }
783         }
784         break;
785 
786     default:
787         break;
788     }
789 
790     return (FALSE);
791 }
792 
793 
794 /*******************************************************************************
795  *
796  * FUNCTION:    AslError
797  *
798  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
799  *              MessageId           - Index into global message buffer
800  *              Op                  - Parse node where error happened
801  *              ExtraMessage        - additional error message
802  *
803  * RETURN:      None
804  *
805  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
806  *              except the parser.)
807  *
808  ******************************************************************************/
809 
810 void
811 AslError (
812     UINT8                   Level,
813     UINT8                   MessageId,
814     ACPI_PARSE_OBJECT       *Op,
815     char                    *ExtraMessage)
816 {
817 
818     /* Check if user wants to ignore this exception */
819 
820     if (AslIsExceptionDisabled (Level, MessageId))
821     {
822         return;
823     }
824 
825     if (Op)
826     {
827         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
828             Op->Asl.LogicalLineNumber,
829             Op->Asl.LogicalByteOffset,
830             Op->Asl.Column,
831             Op->Asl.Filename, ExtraMessage);
832     }
833     else
834     {
835         AslCommonError (Level, MessageId, 0,
836             0, 0, 0, NULL, ExtraMessage);
837     }
838 }
839 
840 
841 /*******************************************************************************
842  *
843  * FUNCTION:    AslCoreSubsystemError
844  *
845  * PARAMETERS:  Op                  - Parse node where error happened
846  *              Status              - The ACPI CA Exception
847  *              ExtraMessage        - additional error message
848  *              Abort               - TRUE -> Abort compilation
849  *
850  * RETURN:      None
851  *
852  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPI
853  *              CA core subsystem.
854  *
855  ******************************************************************************/
856 
857 void
858 AslCoreSubsystemError (
859     ACPI_PARSE_OBJECT       *Op,
860     ACPI_STATUS             Status,
861     char                    *ExtraMessage,
862     BOOLEAN                 Abort)
863 {
864 
865     sprintf (MsgBuffer, "%s %s", AcpiFormatException (Status), ExtraMessage);
866 
867     if (Op)
868     {
869         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, Op->Asl.LineNumber,
870                         Op->Asl.LogicalLineNumber,
871                         Op->Asl.LogicalByteOffset,
872                         Op->Asl.Column,
873                         Op->Asl.Filename, MsgBuffer);
874     }
875     else
876     {
877         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION, 0,
878                         0, 0, 0, NULL, MsgBuffer);
879     }
880 
881     if (Abort)
882     {
883         AslAbort ();
884     }
885 }
886 
887 
888 /*******************************************************************************
889  *
890  * FUNCTION:    AslCompilererror
891  *
892  * PARAMETERS:  CompilerMessage         - Error message from the parser
893  *
894  * RETURN:      Status (0 for now)
895  *
896  * DESCRIPTION: Report an error situation discovered in a production
897  *              NOTE: don't change the name of this function, it is called
898  *              from the auto-generated parser.
899  *
900  ******************************************************************************/
901 
902 int
903 AslCompilererror (
904     const char              *CompilerMessage)
905 {
906 
907     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
908         Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
909         Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
910         ACPI_CAST_PTR (char, CompilerMessage));
911 
912     return (0);
913 }
914