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