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