Home | History | Annotate | Line # | Download | only in compiler
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