Home | History | Annotate | Line # | Download | only in compiler
aslerror.c revision 1.9
      1 /******************************************************************************
      2  *
      3  * Module Name: aslerror - Error handling and statistics
      4  *
      5  *****************************************************************************/
      6 
      7 /*
      8  * Copyright (C) 2000 - 2017, 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     AslLogNewError (Level, MessageId, CurrentLineNumber, LogicalLineNumber,
    817         LogicalByteOffset, Column, Filename, ExtraMessage,
    818         NULL, NULL);
    819 }
    820 
    821 
    822 /*******************************************************************************
    823  *
    824  * FUNCTION:    AslLogNewError
    825  *
    826  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
    827  *              MessageId           - Index into global message buffer
    828  *              CurrentLineNumber   - Actual file line number
    829  *              LogicalLineNumber   - Cumulative line number
    830  *              LogicalByteOffset   - Byte offset in source file
    831  *              Column              - Column in current line
    832  *              Filename            - source filename
    833  *              Message             - additional error message
    834  *              SourceLine          - Actual line of source code
    835  *              SubError            - Sub-error associated with this error
    836  *
    837  * RETURN:      None
    838  *
    839  * DESCRIPTION: Create a new error node and add it to the error log
    840  *
    841  ******************************************************************************/
    842 static void
    843 AslLogNewError (
    844     UINT8                   Level,
    845     UINT16                  MessageId,
    846     UINT32                  LineNumber,
    847     UINT32                  LogicalLineNumber,
    848     UINT32                  LogicalByteOffset,
    849     UINT32                  Column,
    850     char                    *Filename,
    851     char                    *Message,
    852     char                    *SourceLine,
    853     ASL_ERROR_MSG           *SubError)
    854 {
    855     ASL_ERROR_MSG           *Enode = NULL;
    856 
    857 
    858     AslInitEnode (&Enode, Level, MessageId, LineNumber, LogicalLineNumber,
    859         LogicalByteOffset, Column, Filename, Message, SourceLine,
    860         SubError);
    861 
    862     /* Add the new node to the error node list */
    863 
    864     AeAddToErrorLog (Enode);
    865 
    866     if (Gbl_DebugFlag)
    867     {
    868         /* stderr is a file, send error to it immediately */
    869 
    870         AePrintException (ASL_FILE_STDERR, Enode, NULL);
    871     }
    872 
    873     Gbl_ExceptionCount[Level]++;
    874     if (Gbl_ExceptionCount[ASL_ERROR] > ASL_MAX_ERROR_COUNT)
    875     {
    876         printf ("\nMaximum error count (%u) exceeded\n", ASL_MAX_ERROR_COUNT);
    877 
    878         Gbl_SourceLine = 0;
    879         Gbl_NextError = Gbl_ErrorLog;
    880         CmCleanupAndExit ();
    881         exit(1);
    882     }
    883 
    884     return;
    885 }
    886 
    887 /*******************************************************************************
    888  *
    889  * FUNCTION:    AslIsExceptionIgnored
    890  *
    891  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
    892  *              MessageId       - Index into global message buffer
    893  *
    894  * RETURN:      BOOLEAN
    895  *
    896  * DESCRIPTION: Check if a particular exception is ignored. In this case it
    897  *              means that the exception is (expected or disabled.
    898  *
    899  ******************************************************************************/
    900 
    901 BOOLEAN
    902 AslIsExceptionIgnored (
    903     UINT8                   Level,
    904     UINT16                  MessageId)
    905 {
    906     BOOLEAN                 ExceptionIgnored;
    907 
    908 
    909     /* Note: this allows exception to be disabled and expected */
    910 
    911     ExceptionIgnored = AslIsExceptionDisabled (Level, MessageId);
    912     ExceptionIgnored |= AslIsExceptionExpected (Level, MessageId);
    913 
    914     return (Gbl_AllExceptionsDisabled || ExceptionIgnored);
    915 }
    916 
    917 
    918 /*******************************************************************************
    919  *
    920  * FUNCTION:    AslCheckExpectException
    921  *
    922  * PARAMETERS:  none
    923  *
    924  * RETURN:      none
    925  *
    926  * DESCRIPTION: Check the global expected messages table and raise an error
    927  *              for each message that has not been received.
    928  *
    929  ******************************************************************************/
    930 
    931 void
    932 AslCheckExpectedExceptions (
    933     void)
    934 {
    935     UINT8                   i;
    936 
    937 
    938     for (i = 0; i < Gbl_ExpectedMessagesIndex; ++i)
    939     {
    940         if (!Gbl_ExpectedMessages[i].MessageReceived)
    941         {
    942             AslError (ASL_ERROR, ASL_MSG_EXCEPTION_NOT_RECEIVED, NULL,
    943                 Gbl_ExpectedMessages[i].MessageIdStr);
    944         }
    945     }
    946 }
    947 
    948 
    949 /*******************************************************************************
    950  *
    951  * FUNCTION:    AslExpectException
    952  *
    953  * PARAMETERS:  MessageIdString     - ID of excepted exception during compile
    954  *
    955  * RETURN:      Status
    956  *
    957  * DESCRIPTION: Enter a message ID into the global expected messages table
    958  *              If these messages are not raised during the compilation, throw
    959  *              an error.
    960  *
    961  ******************************************************************************/
    962 
    963 ACPI_STATUS
    964 AslExpectException (
    965     char                    *MessageIdString)
    966 {
    967     UINT32                  MessageId;
    968 
    969 
    970     /* Convert argument to an integer and validate it */
    971 
    972     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
    973 
    974     if (MessageId > 6999)
    975     {
    976         printf ("\"%s\" is not a valid warning/remark/erro ID\n",
    977             MessageIdString);
    978         return (AE_BAD_PARAMETER);
    979     }
    980 
    981     /* Insert value into the global expected message array */
    982 
    983     if (Gbl_ExpectedMessagesIndex >= ASL_MAX_EXPECTED_MESSAGES)
    984     {
    985         printf ("Too many messages have been registered as expected (max %u)\n",
    986             ASL_MAX_DISABLED_MESSAGES);
    987         return (AE_LIMIT);
    988     }
    989 
    990     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageId = MessageId;
    991     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageIdStr = MessageIdString;
    992     Gbl_ExpectedMessages[Gbl_ExpectedMessagesIndex].MessageReceived = FALSE;
    993     Gbl_ExpectedMessagesIndex++;
    994     return (AE_OK);
    995 }
    996 
    997 
    998 /*******************************************************************************
    999  *
   1000  * FUNCTION:    AslDisableException
   1001  *
   1002  * PARAMETERS:  MessageIdString     - ID to be disabled
   1003  *
   1004  * RETURN:      Status
   1005  *
   1006  * DESCRIPTION: Enter a message ID into the global disabled messages table
   1007  *
   1008  ******************************************************************************/
   1009 
   1010 ACPI_STATUS
   1011 AslDisableException (
   1012     char                    *MessageIdString)
   1013 {
   1014     UINT32                  MessageId;
   1015 
   1016 
   1017     /* Convert argument to an integer and validate it */
   1018 
   1019     MessageId = (UINT32) strtoul (MessageIdString, NULL, 0);
   1020 
   1021     if ((MessageId < 2000) || (MessageId > 6999))
   1022     {
   1023         printf ("\"%s\" is not a valid warning/remark/error ID\n",
   1024             MessageIdString);
   1025         return (AE_BAD_PARAMETER);
   1026     }
   1027 
   1028     /* Insert value into the global disabled message array */
   1029 
   1030     if (Gbl_DisabledMessagesIndex >= ASL_MAX_DISABLED_MESSAGES)
   1031     {
   1032         printf ("Too many messages have been disabled (max %u)\n",
   1033             ASL_MAX_DISABLED_MESSAGES);
   1034         return (AE_LIMIT);
   1035     }
   1036 
   1037     Gbl_DisabledMessages[Gbl_DisabledMessagesIndex] = MessageId;
   1038     Gbl_DisabledMessagesIndex++;
   1039     return (AE_OK);
   1040 }
   1041 
   1042 
   1043 /*******************************************************************************
   1044  *
   1045  * FUNCTION:    AslIsExceptionDisabled
   1046  *
   1047  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
   1048  *              MessageId       - Index into global message buffer
   1049  *
   1050  * RETURN:      TRUE if exception/message should be ignored
   1051  *
   1052  * DESCRIPTION: Check if the user has specified options such that this
   1053  *              exception should be ignored
   1054  *
   1055  ******************************************************************************/
   1056 
   1057 static BOOLEAN
   1058 AslIsExceptionExpected (
   1059     UINT8                   Level,
   1060     UINT16                  MessageId)
   1061 {
   1062     UINT32                  EncodedMessageId;
   1063     UINT32                  i;
   1064 
   1065 
   1066     /* Mark this exception as received */
   1067 
   1068     EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
   1069     for (i = 0; i < Gbl_ExpectedMessagesIndex; i++)
   1070     {
   1071         /* Simple implementation via fixed array */
   1072 
   1073         if (EncodedMessageId == Gbl_ExpectedMessages[i].MessageId)
   1074         {
   1075             return (Gbl_ExpectedMessages[i].MessageReceived = TRUE);
   1076         }
   1077     }
   1078 
   1079     return (FALSE);
   1080 }
   1081 
   1082 
   1083 /*******************************************************************************
   1084  *
   1085  * FUNCTION:    AslIsExceptionDisabled
   1086  *
   1087  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
   1088  *              MessageId           - Index into global message buffer
   1089  *
   1090  * RETURN:      TRUE if exception/message should be ignored
   1091  *
   1092  * DESCRIPTION: Check if the user has specified options such that this
   1093  *              exception should be ignored
   1094  *
   1095  ******************************************************************************/
   1096 
   1097 static BOOLEAN
   1098 AslIsExceptionDisabled (
   1099     UINT8                   Level,
   1100     UINT16                  MessageId)
   1101 {
   1102     UINT32                  EncodedMessageId;
   1103     UINT32                  i;
   1104 
   1105 
   1106     switch (Level)
   1107     {
   1108     case ASL_WARNING2:
   1109     case ASL_WARNING3:
   1110 
   1111         /* Check for global disable via -w1/-w2/-w3 options */
   1112 
   1113         if (Level > Gbl_WarningLevel)
   1114         {
   1115             return (TRUE);
   1116         }
   1117         /* Fall through */
   1118 
   1119     case ASL_WARNING:
   1120     case ASL_REMARK:
   1121     case ASL_ERROR:
   1122         /*
   1123          * Ignore this error/warning/remark if it has been disabled by
   1124          * the user (-vw option)
   1125          */
   1126         EncodedMessageId = AeBuildFullExceptionCode (Level, MessageId);
   1127         for (i = 0; i < Gbl_DisabledMessagesIndex; i++)
   1128         {
   1129             /* Simple implementation via fixed array */
   1130 
   1131             if (EncodedMessageId == Gbl_DisabledMessages[i])
   1132             {
   1133                 return (TRUE);
   1134             }
   1135         }
   1136         break;
   1137 
   1138     default:
   1139         break;
   1140     }
   1141 
   1142     return (FALSE);
   1143 }
   1144 
   1145 
   1146 /*******************************************************************************
   1147  *
   1148  * FUNCTION:    AslDualParseOpError
   1149  *
   1150  * PARAMETERS:  Level           - Seriousness (Warning/error, etc.)
   1151  *              MainMsgId       - Index into global message buffer
   1152  *              MainOp          - Parse node where error happened
   1153  *              MainMsg         - Message pertaining to the MainOp
   1154  *              SubMsgId        - Index into global message buffer
   1155  *              SubOp           - Additional parse node for better message
   1156  *              SubMsg          - Message pertainint to SubOp
   1157  *
   1158  *
   1159  * RETURN:      None
   1160  *
   1161  * DESCRIPTION: Main error reporting routine for the ASL compiler for error
   1162  *              messages that point to multiple parse objects.
   1163  *
   1164  ******************************************************************************/
   1165 
   1166 void
   1167 AslDualParseOpError (
   1168     UINT8                   Level,
   1169     UINT16                  MainMsgId,
   1170     ACPI_PARSE_OBJECT       *MainOp,
   1171     char                    *MainMsg,
   1172     UINT16                  SubMsgId,
   1173     ACPI_PARSE_OBJECT       *SubOp,
   1174     char                    *SubMsg)
   1175 {
   1176     ASL_ERROR_MSG           *SubEnode = NULL;
   1177 
   1178 
   1179     /* Check if user wants to ignore this exception */
   1180 
   1181     if (AslIsExceptionIgnored (Level, MainMsgId) || !MainOp)
   1182     {
   1183         return;
   1184     }
   1185 
   1186     if (SubOp)
   1187     {
   1188         AslInitEnode (&SubEnode, Level, SubMsgId, SubOp->Asl.LineNumber,
   1189             SubOp->Asl.LogicalLineNumber, SubOp->Asl.LogicalByteOffset,
   1190             SubOp->Asl.Column, SubOp->Asl.Filename, SubMsg,
   1191             NULL, NULL);
   1192     }
   1193 
   1194     AslLogNewError (Level, MainMsgId, MainOp->Asl.LineNumber,
   1195         MainOp->Asl.LogicalLineNumber, MainOp->Asl.LogicalByteOffset,
   1196         MainOp->Asl.Column, MainOp->Asl.Filename, MainMsg,
   1197         NULL, SubEnode);
   1198 }
   1199 
   1200 
   1201 /*******************************************************************************
   1202  *
   1203  * FUNCTION:    AslError
   1204  *
   1205  * PARAMETERS:  Level               - Seriousness (Warning/error, etc.)
   1206  *              MessageId           - Index into global message buffer
   1207  *              Op                  - Parse node where error happened
   1208  *              ExtraMessage        - additional error message
   1209  *
   1210  * RETURN:      None
   1211  *
   1212  * DESCRIPTION: Main error reporting routine for the ASL compiler (all code
   1213  *              except the parser.)
   1214  *
   1215  ******************************************************************************/
   1216 
   1217 void
   1218 AslError (
   1219     UINT8                   Level,
   1220     UINT16                  MessageId,
   1221     ACPI_PARSE_OBJECT       *Op,
   1222     char                    *ExtraMessage)
   1223 {
   1224     if (Op)
   1225     {
   1226         AslCommonError (Level, MessageId, Op->Asl.LineNumber,
   1227             Op->Asl.LogicalLineNumber,
   1228             Op->Asl.LogicalByteOffset,
   1229             Op->Asl.Column,
   1230             Op->Asl.Filename, ExtraMessage);
   1231     }
   1232     else
   1233     {
   1234         AslCommonError (Level, MessageId, 0,
   1235             0, 0, 0, NULL, ExtraMessage);
   1236     }
   1237 }
   1238 
   1239 
   1240 /*******************************************************************************
   1241  *
   1242  * FUNCTION:    AslCoreSubsystemError
   1243  *
   1244  * PARAMETERS:  Op                  - Parse node where error happened
   1245  *              Status              - The ACPICA Exception
   1246  *              ExtraMessage        - additional error message
   1247  *              Abort               - TRUE -> Abort compilation
   1248  *
   1249  * RETURN:      None
   1250  *
   1251  * DESCRIPTION: Error reporting routine for exceptions returned by the ACPICA
   1252  *              core subsystem.
   1253  *
   1254  ******************************************************************************/
   1255 
   1256 void
   1257 AslCoreSubsystemError (
   1258     ACPI_PARSE_OBJECT       *Op,
   1259     ACPI_STATUS             Status,
   1260     char                    *ExtraMessage,
   1261     BOOLEAN                 Abort)
   1262 {
   1263 
   1264     snprintf (MsgBuffer, sizeof(MsgBuffer), "%s %s", AcpiFormatException (Status), ExtraMessage);
   1265 
   1266     if (Op)
   1267     {
   1268         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1269             Op->Asl.LineNumber,
   1270             Op->Asl.LogicalLineNumber,
   1271             Op->Asl.LogicalByteOffset,
   1272             Op->Asl.Column,
   1273             Op->Asl.Filename, MsgBuffer);
   1274     }
   1275     else
   1276     {
   1277         AslCommonError (ASL_ERROR, ASL_MSG_CORE_EXCEPTION,
   1278             0, 0, 0, 0, NULL, MsgBuffer);
   1279     }
   1280 
   1281     if (Abort)
   1282     {
   1283         AslAbort ();
   1284     }
   1285 }
   1286 
   1287 
   1288 /*******************************************************************************
   1289  *
   1290  * FUNCTION:    AslCompilererror
   1291  *
   1292  * PARAMETERS:  CompilerMessage         - Error message from the parser
   1293  *
   1294  * RETURN:      Status (0 for now)
   1295  *
   1296  * DESCRIPTION: Report an error situation discovered in a production
   1297  *              NOTE: don't change the name of this function, it is called
   1298  *              from the auto-generated parser.
   1299  *
   1300  ******************************************************************************/
   1301 
   1302 int
   1303 AslCompilererror (
   1304     const char              *CompilerMessage)
   1305 {
   1306 
   1307     Gbl_SyntaxError++;
   1308 
   1309     AslCommonError (ASL_ERROR, ASL_MSG_SYNTAX, Gbl_CurrentLineNumber,
   1310         Gbl_LogicalLineNumber, Gbl_CurrentLineOffset,
   1311         Gbl_CurrentColumn, Gbl_Files[ASL_FILE_INPUT].Filename,
   1312         ACPI_CAST_PTR (char, CompilerMessage));
   1313 
   1314     return (0);
   1315 }
   1316