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