Home | History | Annotate | Line # | Download | only in compiler
aslerror.c revision 1.10
      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 
     97 /*******************************************************************************
     98  *
     99  * FUNCTION:    AslAbort
    100  *
    101  * PARAMETERS:  None
    102  *
    103  * RETURN:      None
    104  *
    105  * DESCRIPTION: Dump the error log and abort the compiler. Used for serious
    106  *              I/O errors.
    107  *
    108  ******************************************************************************/
    109 
    110 void
    111 AslAbort (
    112     void)
    113 {
    114 
    115     AePrintErrorLog (ASL_FILE_STDERR);
    116     if (Gbl_DebugFlag)
    117     {
    118         /* Print error summary to stdout also */
    119 
    120         AePrintErrorLog (ASL_FILE_STDOUT);
    121     }
    122 
    123     exit (1);
    124 }
    125 
    126 
    127 /*******************************************************************************
    128  *
    129  * FUNCTION:    AeClearErrorLog
    130  *
    131  * PARAMETERS:  None
    132  *
    133  * RETURN:      None
    134  *
    135  * DESCRIPTION: Empty the error list
    136  *
    137  ******************************************************************************/
    138 
    139 void
    140 AeClearErrorLog (
    141     void)
    142 {
    143     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
    144     ASL_ERROR_MSG           *Next;
    145 
    146 
    147     /* Walk the error node list */
    148 
    149     while (Enode)
    150     {
    151         Next = Enode->Next;
    152         ACPI_FREE (Enode);
    153         Enode = Next;
    154     }
    155 
    156     Gbl_ErrorLog = NULL;
    157 }
    158 
    159 
    160 /*******************************************************************************
    161  *
    162  * FUNCTION:    AeAddToErrorLog
    163  *
    164  * PARAMETERS:  Enode       - An error node to add to the log
    165  *
    166  * RETURN:      None
    167  *
    168  * DESCRIPTION: Add a new error node to the error log. The error log is
    169  *              ordered by the "logical" line number (cumulative line number
    170  *              including all include files.)
    171  *
    172  ******************************************************************************/
    173 
    174 static void
    175 AeAddToErrorLog (
    176     ASL_ERROR_MSG           *Enode)
    177 {
    178     ASL_ERROR_MSG           *Next;
    179     ASL_ERROR_MSG           *Prev;
    180 
    181 
    182     /* If Gbl_ErrorLog is null, this is the first error node */
    183 
    184     if (!Gbl_ErrorLog)
    185     {
    186         Gbl_ErrorLog = Enode;
    187         return;
    188     }
    189 
    190     /*
    191      * Walk error list until we find a line number greater than ours.
    192      * List is sorted according to line number.
    193      */
    194     Prev = NULL;
    195     Next = Gbl_ErrorLog;
    196 
    197     while ((Next) && (Next->LogicalLineNumber <= Enode->LogicalLineNumber))
    198     {
    199         Prev = Next;
    200         Next = Next->Next;
    201     }
    202 
    203     /* Found our place in the list */
    204 
    205     Enode->Next = Next;
    206 
    207     if (Prev)
    208     {
    209         Prev->Next = Enode;
    210     }
    211     else
    212     {
    213         Gbl_ErrorLog = Enode;
    214     }
    215 }
    216 
    217 
    218 /*******************************************************************************
    219  *
    220  * FUNCTION:    AeDecodeErrorMessageId
    221  *
    222  * PARAMETERS:  OutputFile      - Output file
    223  *              Enode           - Error node to print
    224  *              PrematureEOF    - True = PrematureEOF has been reached
    225  *              Total           - Total legth of line
    226  *
    227  * RETURN:      None
    228  *
    229  * DESCRIPTION: Print the source line of an error.
    230  *
    231  ******************************************************************************/
    232 
    233 static void
    234 AeDecodeErrorMessageId (
    235     FILE                    *OutputFile,
    236     ASL_ERROR_MSG           *Enode,
    237     BOOLEAN                 PrematureEOF,
    238     UINT32                  Total)
    239 {
    240     UINT32                  MsgLength;
    241     const char              *MainMessage;
    242     char                    *ExtraMessage;
    243     UINT32                  SourceColumn;
    244     UINT32                  ErrorColumn;
    245 
    246 
    247     fprintf (OutputFile, "%s %4.4d -",
    248         AeDecodeExceptionLevel (Enode->Level),
    249         AeBuildFullExceptionCode (Enode->Level, Enode->MessageId));
    250 
    251     MainMessage = AeDecodeMessageId (Enode->MessageId);
    252     ExtraMessage = Enode->Message;
    253 
    254     /* If a NULL line number, just print the decoded message */
    255 
    256     if (!Enode->LineNumber)
    257     {
    258         fprintf (OutputFile, " %s %s\n\n", MainMessage, ExtraMessage);
    259         return;
    260     }
    261 
    262     MsgLength = strlen (MainMessage);
    263     if (MsgLength == 0)
    264     {
    265         /* Use the secondary/extra message as main message */
    266 
    267         MainMessage = Enode->Message;
    268         if (!MainMessage)
    269         {
    270             MainMessage = "";
    271         }
    272 
    273         MsgLength = strlen (MainMessage);
    274         ExtraMessage = NULL;
    275     }
    276 
    277     if (Gbl_VerboseErrors && !PrematureEOF)
    278     {
    279         if (Total >= 256)
    280         {
    281             fprintf (OutputFile, "    %s",
    282                 MainMessage);
    283         }
    284         else
    285         {
    286             SourceColumn = Enode->Column + Enode->FilenameLength + 6 + 2;
    287             ErrorColumn = ASL_ERROR_LEVEL_LENGTH + 5 + 2 + 1;
    288 
    289             if ((MsgLength + ErrorColumn) < (SourceColumn - 1))
    290             {
    291                 fprintf (OutputFile, "%*s%s",
    292                     (int) ((SourceColumn - 1) - ErrorColumn),
    293                     MainMessage, " ^ ");
    294             }
    295             else
    296             {
    297                 fprintf (OutputFile, "%*s %s",
    298                     (int) ((SourceColumn - ErrorColumn) + 1), "^",
    299                     MainMessage);
    300             }
    301         }
    302     }
    303     else
    304     {
    305         fprintf (OutputFile, " %s", MainMessage);
    306     }
    307 
    308     /* Print the extra info message if present */
    309 
    310     if (ExtraMessage)
    311     {
    312         fprintf (OutputFile, " (%s)", ExtraMessage);
    313     }
    314 
    315     if (PrematureEOF)
    316     {
    317         fprintf (OutputFile, " and premature End-Of-File");
    318     }
    319 
    320     fprintf (OutputFile, "\n");
    321     if (Gbl_VerboseErrors && !Enode->SubError)
    322     {
    323         fprintf (OutputFile, "\n");
    324     }
    325 }
    326 
    327 
    328 /*******************************************************************************
    329  *
    330  * FUNCTION:    AePrintErrorSourceLine
    331  *
    332  * PARAMETERS:  OutputFile      - Output file
    333  *              Enode           - Error node to print
    334  *              PrematureEOF    - True = PrematureEOF has been reached
    335  *              Total           - amount of characters printed so far
    336  *
    337  *
    338  * RETURN:      Status
    339  *
    340  * DESCRIPTION: Print the source line of an error.
    341  *
    342  ******************************************************************************/
    343 
    344 static ACPI_STATUS
    345 AePrintErrorSourceLine (
    346     FILE                    *OutputFile,
    347     ASL_ERROR_MSG           *Enode,
    348     BOOLEAN                 *PrematureEOF,
    349     UINT32                  *Total)
    350 {
    351     UINT8                   SourceByte;
    352     int                     Actual;
    353     size_t                  RActual;
    354     FILE                    *SourceFile = NULL;
    355     long                    FileSize;
    356 
    357 
    358     if (!Enode->SourceLine)
    359     {
    360         /*
    361          * Use the merged header/source file if present, otherwise
    362          * use input file
    363          */
    364         SourceFile = Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Handle;
    365         if (!SourceFile)
    366         {
    367             SourceFile = Gbl_Files[ASL_FILE_INPUT].Handle;
    368         }
    369 
    370         if (SourceFile)
    371         {
    372             /* Determine if the error occurred at source file EOF */
    373 
    374             fseek (SourceFile, 0, SEEK_END);
    375             FileSize = ftell (SourceFile);
    376 
    377             if ((long) Enode->LogicalByteOffset >= FileSize)
    378             {
    379                 *PrematureEOF = TRUE;
    380             }
    381         }
    382         else
    383         {
    384             fprintf (OutputFile,
    385                 "[*** iASL: Source File Does not exist ***]\n");
    386             return AE_IO_ERROR;
    387         }
    388     }
    389 
    390     /* Print filename and line number if present and valid */
    391 
    392     if (Gbl_VerboseErrors)
    393     {
    394         fprintf (OutputFile, "%-8s", Enode->Filename);
    395 
    396         if (Enode->SourceLine && Enode->LineNumber)
    397         {
    398             fprintf (OutputFile, " %6u: %s",
    399                 Enode->LineNumber, Enode->SourceLine);
    400         }
    401         else if (Enode->LineNumber)
    402         {
    403             fprintf (OutputFile, " %6u: ", Enode->LineNumber);
    404 
    405             /*
    406              * If not at EOF, get the corresponding source code line
    407              * and display it. Don't attempt this if we have a
    408              * premature EOF condition.
    409              */
    410             if (*PrematureEOF)
    411             {
    412                 fprintf (OutputFile, "\n");
    413                 return AE_OK;
    414             }
    415             /*
    416              * Seek to the offset in the combined source file,
    417              * read the source line, and write it to the output.
    418              */
    419             Actual = fseek (SourceFile,
    420                 (long) Enode->LogicalByteOffset, (int) SEEK_SET);
    421             if (Actual)
    422             {
    423                 fprintf (OutputFile,
    424                     "[*** iASL: Seek error on source code temp file %s ***]",
    425                     Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    426 
    427                 fprintf (OutputFile, "\n");
    428                 return AE_OK;
    429             }
    430             RActual = fread (&SourceByte, 1, 1, SourceFile);
    431             if (RActual != 1)
    432             {
    433                 fprintf (OutputFile,
    434                     "[*** iASL: Read error on source code temp file %s ***]",
    435                     Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    436                 return AE_IO_ERROR;
    437             }
    438                 /* Read/write the source line, up to the maximum line length */
    439 
    440             while (RActual && SourceByte && (SourceByte != '\n'))
    441             {
    442                 if (*Total < 256)
    443                 {
    444                     /* After the max line length, we will just read the line, no write */
    445 
    446                     if (fwrite (&SourceByte, 1, 1, OutputFile) != 1)
    447                     {
    448                         printf ("[*** iASL: Write error on output file ***]\n");
    449                         return AE_IO_ERROR;
    450                     }
    451                 }
    452                 else if (*Total == 256)
    453                 {
    454                     fprintf (OutputFile,
    455                         "\n[*** iASL: Very long input line, message below refers to column %u ***]",
    456                         Enode->Column);
    457                 }
    458 
    459                 RActual = fread (&SourceByte, 1, 1, SourceFile);
    460                 if (RActual != 1)
    461                 {
    462                     fprintf (OutputFile,
    463                         "[*** iASL: Read error on source code temp file %s ***]",
    464                         Gbl_Files[ASL_FILE_SOURCE_OUTPUT].Filename);
    465 
    466                     return AE_IO_ERROR;
    467                 }
    468                 *Total += 1;
    469             }
    470 
    471             fprintf (OutputFile, "\n");
    472         }
    473     }
    474     else
    475     {
    476         /*
    477          * Less verbose version of the error message, enabled via the
    478          * -vi switch. The format is compatible with MS Visual Studio.
    479          */
    480         fprintf (OutputFile, "%s", Enode->Filename);
    481 
    482         if (Enode->LineNumber)
    483         {
    484             fprintf (OutputFile, "(%u) : ",
    485                 Enode->LineNumber);
    486         }
    487     }
    488 
    489     return AE_OK;
    490 }
    491 
    492 /*******************************************************************************
    493  *
    494  * FUNCTION:    AePrintException
    495  *
    496  * PARAMETERS:  FileId          - ID of output file
    497  *              Enode           - Error node to print
    498  *              Header          - Additional text before each message
    499  *
    500  * RETURN:      None
    501  *
    502  * DESCRIPTION: Print the contents of an error node.
    503  *
    504  * NOTE:        We don't use the FlxxxFile I/O functions here because on error
    505  *              they abort the compiler and call this function!  Since we
    506  *              are reporting errors here, we ignore most output errors and
    507  *              just try to get out as much as we can.
    508  *
    509  ******************************************************************************/
    510 
    511 void
    512 AePrintException (
    513     UINT32                  FileId,
    514     ASL_ERROR_MSG           *Enode,
    515     char                    *Header)
    516 {
    517     FILE                    *OutputFile;
    518     BOOLEAN                 PrematureEOF = FALSE;
    519     UINT32                  Total = 0;
    520     ACPI_STATUS             Status;
    521     ASL_ERROR_MSG           *Child = Enode->SubError;
    522 
    523 
    524     if (Gbl_NoErrors)
    525     {
    526         return;
    527     }
    528 
    529     /*
    530      * Only listing files have a header, and remarks/optimizations
    531      * are always output
    532      */
    533     if (!Header)
    534     {
    535         /* Ignore remarks if requested */
    536 
    537         switch (Enode->Level)
    538         {
    539         case ASL_WARNING:
    540         case ASL_WARNING2:
    541         case ASL_WARNING3:
    542 
    543             if (!Gbl_DisplayWarnings)
    544             {
    545                 return;
    546             }
    547             break;
    548 
    549         case ASL_REMARK:
    550 
    551             if (!Gbl_DisplayRemarks)
    552             {
    553                 return;
    554             }
    555             break;
    556 
    557         case ASL_OPTIMIZATION:
    558 
    559             if (!Gbl_DisplayOptimizations)
    560             {
    561                 return;
    562             }
    563             break;
    564 
    565         default:
    566 
    567             break;
    568         }
    569     }
    570 
    571     /* Get the various required file handles */
    572 
    573     OutputFile = Gbl_Files[FileId].Handle;
    574 
    575     if (Header)
    576     {
    577         fprintf (OutputFile, "%s", Header);
    578     }
    579 
    580     if (!Enode->Filename)
    581     {
    582         AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
    583         return;
    584     }
    585 
    586     Status = AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
    587     if (ACPI_FAILURE (Status))
    588     {
    589         return;
    590     }
    591 
    592     /* If a NULL message ID, just print the raw message */
    593 
    594     if (Enode->MessageId == 0)
    595     {
    596         fprintf (OutputFile, "%s\n", Enode->Message);
    597         return;
    598     }
    599 
    600     AeDecodeErrorMessageId (OutputFile, Enode, PrematureEOF, Total);
    601 
    602     while (Child)
    603     {
    604         fprintf (OutputFile, "\n");
    605         AePrintSubError (OutputFile, Child);
    606         Child = Child->SubError;
    607     }
    608 }
    609 
    610 
    611 /*******************************************************************************
    612  *
    613  * FUNCTION:    AePrintSubError
    614  *
    615  * PARAMETERS:  OutputFile      - Output file
    616  *              Enode           - Error node to print
    617  *
    618  * RETURN:      None
    619  *
    620  * DESCRIPTION: Print the contents of an error nodes. This function is tailored
    621  *              to print error nodes that are SubErrors within ASL_ERROR_MSG
    622  *
    623  ******************************************************************************/
    624 
    625 static void
    626 AePrintSubError (
    627     FILE                    *OutputFile,
    628     ASL_ERROR_MSG           *Enode)
    629 {
    630     UINT32                  Total = 0;
    631     BOOLEAN                 PrematureEOF = FALSE;
    632     const char              *MainMessage;
    633 
    634 
    635     MainMessage = AeDecodeMessageId (Enode->MessageId);
    636 
    637     fprintf (OutputFile, "    %s%s", MainMessage, "\n    ");
    638     (void) AePrintErrorSourceLine (OutputFile, Enode, &PrematureEOF, &Total);
    639     fprintf (OutputFile, "\n");
    640 }
    641 
    642 
    643 /*******************************************************************************
    644  *
    645  * FUNCTION:    AePrintErrorLog
    646  *
    647  * PARAMETERS:  FileId           - Where to output the error log
    648  *
    649  * RETURN:      None
    650  *
    651  * DESCRIPTION: Print the entire contents of the error log
    652  *
    653  ******************************************************************************/
    654 
    655 void
    656 AePrintErrorLog (
    657     UINT32                  FileId)
    658 {
    659     ASL_ERROR_MSG           *Enode = Gbl_ErrorLog;
    660 
    661 
    662     /* Walk the error node list */
    663 
    664     while (Enode)
    665     {
    666         AePrintException (FileId, Enode, NULL);
    667         Enode = Enode->Next;
    668     }
    669 }
    670 
    671 
    672 /*******************************************************************************
    673  *
    674  * FUNCTION:    AslInitEnode
    675  *
    676  * PARAMETERS:  InputEnode          - Input Error node to initialize
    677  *              Level               - Seriousness (Warning/error, etc.)
    678  *              MessageId           - Index into global message buffer
    679  *              CurrentLineNumber   - Actual file line number
    680  *              LogicalLineNumber   - Cumulative line number
    681  *              LogicalByteOffset   - Byte offset in source file
    682  *              Column              - Column in current line
    683  *              Filename            - source filename
    684  *              ExtraMessage        - additional error message
    685  *              SourceLine          - Line of error source code
    686  *              SubError            - SubError of this InputEnode
    687  *
    688  * RETURN:      None
    689  *
    690  * DESCRIPTION: Initialize an Error node
    691  *
    692  ******************************************************************************/
    693 
    694 static void AslInitEnode (
    695     ASL_ERROR_MSG           **InputEnode,
    696     UINT8                   Level,
    697     UINT16                  MessageId,
    698     UINT32                  LineNumber,
    699     UINT32                  LogicalLineNumber,
    700     UINT32                  LogicalByteOffset,
    701     UINT32                  Column,
    702     char                    *Filename,
    703     char                    *ExtraMessage,
    704     char                    *SourceLine,
    705     ASL_ERROR_MSG           *SubError)
    706 {
    707     ASL_ERROR_MSG           *Enode;
    708 
    709 
    710     *InputEnode = UtLocalCalloc (sizeof (ASL_ERROR_MSG));
    711     Enode = *InputEnode;
    712     Enode->Level                = Level;
    713     Enode->MessageId            = MessageId;
    714     Enode->LineNumber           = LineNumber;
    715     Enode->LogicalLineNumber    = LogicalLineNumber;
    716     Enode->LogicalByteOffset    = LogicalByteOffset;
    717     Enode->Column               = Column;
    718     Enode->SubError             = SubError;
    719     Enode->Message              = NULL;
    720     Enode->SourceLine           = NULL;
    721     Enode->Filename             = NULL;
    722 
    723     if (ExtraMessage)
    724     {
    725         /* Allocate a buffer for the message and a new error node */
    726 
    727         Enode->Message = UtLocalCacheCalloc (strlen (ExtraMessage) + 1);
    728 
    729         /* Keep a copy of the extra message */
    730 
    731         strcpy (Enode->Message, ExtraMessage);
    732     }
    733 
    734     if (SourceLine)
    735     {
    736         Enode->SourceLine = UtLocalCalloc (strlen (SourceLine) + 1);
    737         strcpy (Enode->SourceLine, SourceLine);
    738     }
    739 
    740 
    741     if (Filename)
    742     {
    743         Enode->Filename = Filename;
    744         Enode->FilenameLength = strlen (Filename);
    745         if (Enode->FilenameLength < 6)
    746         {
    747             Enode->FilenameLength = 6;
    748         }
    749     }
    750 }
    751 
    752 
    753 /*******************************************************************************
    754  *
    755  * FUNCTION:    AslCommonError2
    756  *
    757  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    758  *              MessageId           - Index into global message buffer
    759  *              LineNumber          - Actual file line number
    760  *              Column              - Column in current line
    761  *              SourceLine          - Actual source code line
    762  *              Filename            - source filename
    763  *              ExtraMessage        - additional error message
    764  *
    765  * RETURN:      None
    766  *
    767  * DESCRIPTION: Create a new error node and add it to the error log
    768  *
    769  ******************************************************************************/
    770 
    771 void
    772 AslCommonError2 (
    773     UINT8                   Level,
    774     UINT16                  MessageId,
    775     UINT32                  LineNumber,
    776     UINT32                  Column,
    777     char                    *SourceLine,
    778     char                    *Filename,
    779     char                    *ExtraMessage)
    780 {
    781     AslLogNewError (Level, MessageId, LineNumber, LineNumber, 0, Column,
    782         Filename, ExtraMessage, SourceLine, NULL);
    783 }
    784 
    785 
    786 /*******************************************************************************
    787  *
    788  * FUNCTION:    AslCommonError
    789  *
    790  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    791  *              MessageId           - Index into global message buffer
    792  *              CurrentLineNumber   - Actual file line number
    793  *              LogicalLineNumber   - Cumulative line number
    794  *              LogicalByteOffset   - Byte offset in source file
    795  *              Column              - Column in current line
    796  *              Filename            - source filename
    797  *              ExtraMessage        - additional error message
    798  *
    799  * RETURN:      None
    800  *
    801  * DESCRIPTION: Create a new error node and add it to the error log
    802  *
    803  ******************************************************************************/
    804 
    805 void
    806 AslCommonError (
    807     UINT8                   Level,
    808     UINT16                  MessageId,
    809     UINT32                  CurrentLineNumber,
    810     UINT32                  LogicalLineNumber,
    811     UINT32                  LogicalByteOffset,
    812     UINT32                  Column,
    813     char                    *Filename,
    814     char                    *ExtraMessage)
    815 {
    816     /* Check if user wants to ignore this exception */
    817 
    818     if (AslIsExceptionIgnored (Level, MessageId))
    819     {
    820         return;
    821     }
    822 
    823     AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
    824         LogicalByteOffset, Column, Filename, ExtraMessage,
    825         NULL, NULL);
    826 }
    827 
    828 
    829 /*******************************************************************************
    830  *
    831  * FUNCTION:    AslLogNewError
    832  *
    833  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    834  *              MessageId           - Index into global message buffer
    835  *              CurrentLineNumber   - Actual file line number
    836  *              LogicalLineNumber   - Cumulative line number
    837  *              LogicalByteOffset   - Byte offset in source file
    838  *              Column              - Column in current line
    839  *              Filename            - source filename
    840  *              Message             - additional error message
    841  *              SourceLine          - Actual line of source code
    842  *              SubError            - Sub-error associated with this error
    843  *
    844  * RETURN:      None
    845  *
    846  * DESCRIPTION: Create a new error node and add it to the error log
    847  *
    848  ******************************************************************************/
    849 static void
    850 AslLogNewError (
    851     UINT8                   Level,
    852     UINT16                  MessageId,
    853     UINT32                  LineNumber,
    854     UINT32                  LogicalLineNumber,
    855     UINT32                  LogicalByteOffset,
    856     UINT32                  Column,
    857     char                    *Filename,
    858     char                    *Message,
    859     char                    *SourceLine,
    860     ASL_ERROR_MSG           *SubError)
    861 {
    862     ASL_ERROR_MSG           *Enode = NULL;
    863 
    864 
    865     AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber,
    866         LogicalByteOffset, Column, Filename, Message, SourceLine,
    867         SubError);
    868 
    869     /* Add the new node to the error node list */
    870 
    871     AeAddToErrorLog (Enode);
    872 
    873     if (Gbl_DebugFlag)
    874     {
    875         /* stderr is a file, send error to it immediately */
    876 
    877         AePrintException (ASL_FILE_STDERR, Enode, NULL);
    878     }
    879 
    880     Gbl_ExceptionCount[Level]++;
    881     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    882     {
    883         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
    884 
    885         Gbl_SourceLine = 0;
    886         Gbl_NextError = Gbl_ErrorLog;
    887         CmCleanupAndExit ();
    888         exit(1);
    889     }
    890 
    891     return;
    892 }
    893 
    894 /*******************************************************************************
    895  *
    896  * FUNCTION:    AslIsExceptionIgnored
    897  *
    898  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
    899  *              MessageId       - Index into global message buffer
    900  *
    901  * RETURN:      BOOLEAN
    902  *
    903  * DESCRIPTION: Check if a particular exception is ignored. In this case it
    904  *              means that the exception is (expected or disabled.
    905  *
    906  ******************************************************************************/
    907 
    908 BOOLEAN
    909 AslIsExceptionIgnored (
    910     UINT8                   Level,
    911     UINT16                  MessageId)
    912 {
    913     BOOLEAN                 ExceptionIgnored;
    914 
    915 
    916     /* Note: this allows exception to be disabled and expected */
    917 
    918     ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
    919     ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId);
    920 
    921     return (Gbl_AllExceptionsDisabled || ExceptionIgnored);
    922 }
    923 
    924 
    925 /*******************************************************************************
    926  *
    927  * FUNCTION:    AslCheckExpectException
    928  *
    929  * PARAMETERS:  none
    930  *
    931  * RETURN:      none
    932  *
    933  * DESCRIPTION: Check the global expected messages table and raise an error
    934  *              for each message that has not been received.
    935  *
    936  ******************************************************************************/
    937 
    938 void
    939 AslCheckExpectedExceptions (
    940     void)
    941 {
    942     UINT8                   i;
    943 
    944 
    945     for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i)
    946     {
    947         if (!Gbl_ExpectedMessages[i].MessageReceived)
    948         {
    949             AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
    950                 Gbl_ExpectedMessages[i].MessageIdStr);
    951         }
    952     }
    953 }
    954 
    955 
    956 /*******************************************************************************
    957  *
    958  * FUNCTION:    AslExpectException
    959  *
    960  * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
    961  *
    962  * RETURN:      Status
    963  *
    964  * DESCRIPTION: Enter a message ID into the global expected messages table
    965  *              If these messages are not raised during the compilation, throw
    966  *              an error.
    967  *
    968  ******************************************************************************/
    969 
    970 ACPI_STATUS
    971 AslExpectException (
    972     char                    *MessageIdString)
    973 {
    974     UINT32                  MessageId;
    975 
    976 
    977     /* Convert argument to an integer and validate it */
    978 
    979     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
    980 
    981     if (MessageId > 6999)
    982     {
    983         printf ("\"%s\" is not a valid warning/remark/erro ID\n",
    984             MessageIdString);
    985         return (AE_BAD_PARAMETER);
    986     }
    987 
    988     /* Insert value into the global expected message array */
    989 
    990     if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
    991     {
    992         printf ("Too many messages have been registered as expected (max %u)\n",
    993             ASL_MAX_DISABLED_MESSAGES);
    994         return (AE_LIMIT);
    995     }
    996 
    997     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId;
    998     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
    999     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE;
   1000     Gbl_ExpectedMessagesIndex++;
   1001     return (AE_OK);
   1002 }
   1003 
   1004 
   1005 /*******************************************************************************
   1006  *
   1007  * FUNCTION:    AslDisableException
   1008  *
   1009  * PARAMETERS:  MessageIdString     - ID to be disabled
   1010  *
   1011  * RETURN:      Status
   1012  *
   1013  * DESCRIPTION: Enter a message ID into the global disabled messages table
   1014  *
   1015  ******************************************************************************/
   1016 
   1017 ACPI_STATUS
   1018 AslDisableException (
   1019     char                    *MessageIdString)
   1020 {
   1021     UINT32                  MessageId;
   1022 
   1023 
   1024     /* Convert argument to an integer and validate it */
   1025 
   1026     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
   1027 
   1028     if ((MessageId < 2000) || (MessageId > 6999))
   1029     {
   1030         printf ("\"%s\" is not a valid warning/remark/error ID\n",
   1031             MessageIdString);
   1032         return (AE_BAD_PARAMETER);
   1033     }
   1034 
   1035     /* Insert value into the global disabled message array */
   1036 
   1037     if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
   1038     {
   1039         printf ("Too many messages have been disabled (max %u)\n",
   1040             ASL_MAX_DISABLED_MESSAGES);
   1041         return (AE_LIMIT);
   1042     }
   1043 
   1044     Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
   1045     Gbl_DisabledMessagesIndex++;
   1046     return (AE_OK);
   1047 }
   1048 
   1049 
   1050 /*******************************************************************************
   1051  *
   1052  * FUNCTION:    AslIsExceptionDisabled
   1053  *
   1054  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
   1055  *              MessageId       - Index into global message buffer
   1056  *
   1057  * RETURN:      TRUE if exception/message should be ignored
   1058  *
   1059  * DESCRIPTION: Check if the user has specified options such that this
   1060  *              exception should be ignored
   1061  *
   1062  ******************************************************************************/
   1063 
   1064 static BOOLEAN
   1065 AslIsExceptionExpected (
   1066     UINT8                   Level,
   1067     UINT16                  MessageId)
   1068 {
   1069     UINT32                  EncodedMessageId;
   1070     UINT32                  i;
   1071 
   1072 
   1073     /* Mark this exception as received */
   1074 
   1075     EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
   1076     for (i = 0; i < Gbl_ExpectedMessagesIndex; i++)
   1077     {
   1078         /* Simple implementation via fixed array */
   1079 
   1080         if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId)
   1081         {
   1082             return (Gbl_ExpectedMessages[i].MessageReceived = TRUE);
   1083         }
   1084     }
   1085 
   1086     return (FALSE);
   1087 }
   1088 
   1089 
   1090 /*******************************************************************************
   1091  *
   1092  * FUNCTION:    AslIsExceptionDisabled
   1093  *
   1094  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
   1095  *              MessageId           - Index into global message buffer
   1096  *
   1097  * RETURN:      TRUE if exception/message should be ignored
   1098  *
   1099  * DESCRIPTION: Check if the user has specified options such that this
   1100  *              exception should be ignored
   1101  *
   1102  ******************************************************************************/
   1103 
   1104 static BOOLEAN
   1105 AslIsExceptionDisabled (
   1106     UINT8                   Level,
   1107     UINT16                  MessageId)
   1108 {
   1109     UINT32                  EncodedMessageId;
   1110     UINT32                  i;
   1111 
   1112 
   1113     switch (Level)
   1114     {
   1115     case ASL_WARNING2:
   1116     case ASL_WARNING3:
   1117 
   1118         /* Check for global disable via -w1/-w2/-w3 options */
   1119 
   1120         if (Level > Gbl_WarningLevel)
   1121         {
   1122             return (TRUE);
   1123         }
   1124         /* Fall through */
   1125 
   1126     case ASL_WARNING:
   1127     case ASL_REMARK:
   1128     case ASL_ERROR:
   1129         /*
   1130          * Ignore this error/warning/remark if it has been disabled by
   1131          * the user (-vw option)
   1132          */
   1133         EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
   1134         for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
   1135         {
   1136             /* Simple implementation via fixed array */
   1137 
   1138             if (EncodedMessageId == Gbl_DisabledMessages[i])
   1139             {
   1140                 return (TRUE);
   1141             }
   1142         }
   1143         break;
   1144 
   1145     default:
   1146         break;
   1147     }
   1148 
   1149     return (FALSE);
   1150 }
   1151 
   1152 
   1153 /*******************************************************************************
   1154  *
   1155  * FUNCTION:    AslDualParseOpError
   1156  *
   1157  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
   1158  *              MainMsgId       - Index into global message buffer
   1159  *              MainOp          - Parse node where error happened
   1160  *              MainMsg         - Message pertaining to the MainOp
   1161  *              SubMsgId        - Index into global message buffer
   1162  *              SubOp           - Additional parse node for better message
   1163  *              SubMsg          - Message pertainint to SubOp
   1164  *
   1165  *
   1166  * RETURN:      None
   1167  *
   1168  * DESCRIPTION: Main error reporting routine for the ASL compiler for error
   1169  *              messages that point to multiple parse objects.
   1170  *
   1171  ******************************************************************************/
   1172 
   1173 void
   1174 AslDualParseOpError (
   1175     UINT8                   Level,
   1176     UINT16                  MainMsgId,
   1177     ACPI_PARSE_OBJECT       *MainOp,
   1178     char                    *MainMsg,
   1179     UINT16                  SubMsgId,
   1180     ACPI_PARSE_OBJECT       *SubOp,
   1181     char                    *SubMsg)
   1182 {
   1183     ASL_ERROR_MSG           *SubEnode = NULL;
   1184 
   1185 
   1186     /* Check if user wants to ignore this exception */
   1187 
   1188     if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp)
   1189     {
   1190         return;
   1191     }
   1192 
   1193     if (SubOp)
   1194     {
   1195         AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
   1196             SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
   1197             SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
   1198             NULL, NULL);
   1199     }
   1200 
   1201     AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
   1202         MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
   1203         MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
   1204         NULL, SubEnode);
   1205 }
   1206 
   1207 
   1208 /*******************************************************************************
   1209  *
   1210  * FUNCTION:    AslError
   1211  *
   1212  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
   1213  *              MessageId           - Index into global message buffer
   1214  *              Op                  - Parse node where error happened
   1215  *              ExtraMessage        - additional error message
   1216  *
   1217  * RETURN:      None
   1218  *
   1219  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
   1220  *              except the parser.)
   1221  *
   1222  ******************************************************************************/
   1223 
   1224 void
   1225 AslError (
   1226     UINT8                   Level,
   1227     UINT16                  MessageId,
   1228     ACPI_PARSE_OBJECT       *Op,
   1229     char                    *ExtraMessage)
   1230 {
   1231     if (Op)
   1232     {
   1233         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
   1234             Op->Asl.LogicalLineNumber,
   1235             Op->Asl.LogicalByteOffset,
   1236             Op->Asl.Column,
   1237             Op->Asl.Filename, ExtraMessage);
   1238     }
   1239     else
   1240     {
   1241         AslCommonError (Level, MessageId, 0,
   1242             0, 0, 0, NULL, ExtraMessage);
   1243     }
   1244 }
   1245 
   1246 
   1247 /*******************************************************************************
   1248  *
   1249  * FUNCTION:    AslCoreSubsystemError
   1250  *
   1251  * PARAMETERS:  Op                  - Parse node where error happened
   1252  *              Status              - The ACPICA Exception
   1253  *              ExtraMessage        - additional error message
   1254  *              Abort               - TRUE -> Abort compilation
   1255  *
   1256  * RETURN:      None
   1257  *
   1258  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
   1259  *              core subsystem.
   1260  *
   1261  ******************************************************************************/
   1262 
   1263 void
   1264 AslCoreSubsystemError (
   1265     ACPI_PARSE_OBJECT       *Op,
   1266     ACPI_STATUS             Status,
   1267     char                    *ExtraMessage,
   1268     BOOLEAN                 Abort)
   1269 {
   1270 
   1271     snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage);
   1272 
   1273     if (Op)
   1274     {
   1275         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1276             Op->Asl.LineNumber,
   1277             Op->Asl.LogicalLineNumber,
   1278             Op->Asl.LogicalByteOffset,
   1279             Op->Asl.Column,
   1280             Op->Asl.Filename, MsgBuffer);
   1281     }
   1282     else
   1283     {
   1284         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1285             0, 0, 0, 0, NULL, MsgBuffer);
   1286     }
   1287 
   1288     if (Abort)
   1289     {
   1290         AslAbort ();
   1291     }
   1292 }
   1293 
   1294 
   1295 /*******************************************************************************
   1296  *
   1297  * FUNCTION:    AslCompilererror
   1298  *
   1299  * PARAMETERS:  CompilerMessage         - Error message from the parser
   1300  *
   1301  * RETURN:      Status (0 for now)
   1302  *
   1303  * DESCRIPTION: Report an error situation discovered in a production
   1304  *              NOTE: don't change the name of this function, it is called
   1305  *              from the auto-generated parser.
   1306  *
   1307  ******************************************************************************/
   1308 
   1309 int
   1310 AslCompilererror (
   1311     const char              *CompilerMessage)
   1312 {
   1313 
   1314     Gbl_SyntaxError++;
   1315 
   1316     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
   1317         Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
   1318         Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
   1319         ACPI_CAST_PTR (char, CompilerMessage));
   1320 
   1321     return (0);
   1322 }
   1323